Strange bash phenomenon
Hello everyone. This is a little off topic but I find it both perplexing and amusing. I've been spending the last few days enabling support for CyberGuard security devices for the ISCS network security management platform. It has gone very well with the new firmware and has given us a near off the shelf solution.
However, in one of the scripts for automated distribution of the rules, it checks for the presence of existing iptables files. I originally thought I could do something like:
if [ -f iptables* ];then
But the shell expands all the iptables file names and creates an error when passing that many arguments to the test.
So I then thought I could do:
FILES=/etc/config/iptables*
if [ -f ${FILES%% *} ];then
cp /etc/config/iptables* /etc/config/PEPBackup/ 2>/dev/null if [ $? -ne 0 ]; then
echo '[PEP Update Error]' Could not backup up PEP
configuration files >&2
exit 1
fi
fi
I'd trim off everything after the first space and test for that single file. However, it doesn't work. ${FILES%% *} expands to include all the file names. On the other hand, the version below works!
FILES=$(echo /etc/config/iptables*)
if [ -f ${FILES%% *} ];then
cp /etc/config/iptables* /etc/config/PEPBackup/ 2>/dev/null if [ $? -ne 0 ]; then
echo '[PEP Update Error]' Could not backup up PEP
configuration files >&2
exit 1
fi
fi
Any ideas why the latter one works fine but the other does not? Just curious - John
Signature · 8 lines
John A. Sullivan III Open Source Development Corporation +1 207-985-7880 [email protected] If you would like to participate in the development of an open source enterprise class network security management system, please visit http://iscs.sourceforge.net
Quoted 14 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]]On Behalf Of John A. Sullivan III
Sent: Saturday, February 11, 2006 8:45 AM
To: Netfilter users list
Subject: [OT] Strange bash phenomenonCase #1
-------
FILES=/etc/config/iptables*
Quoted 8 lines
[ snipped ]
Case #2
-------
FILES=$(echo/etc/config/iptables*)Any ideas why the latter one works fine but the other does not? Just curious.
Hi John,
It has to do when the shell does the expansion. In the first case when you assign 'FILES=', you're assigning it the string and it's not expanded by the shell. If you want to change the behavior, you can do this:
FILES=${/etc/config/iptables*}btw, Ilove the ${FILES%% *} trick. I didn't know about it. The shell is quite nifty.
-pablo
Quoted 23 lines · Pablo Sanchez
Quoted 12 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]]On Behalf Of John A. Sullivan III
Sent: Saturday, February 11, 2006 8:45 AM
To: Netfilter users list
Subject: [OT] Strange bash phenomenonCase #1
-------
FILES=/etc/config/iptables*Quoted 8 lines
[ snipped ]
Case #2
-------
FILES=$(echo/etc/config/iptables*)Any ideas why the latter one works fine but the other does not? Just curious.
Hi John,
Quoted 9 lines
It has to do when the shell does the expansion. In the first case when you assign 'FILES=', you're assigning it the string and it's not expanded by the shell. If you want to change the behavior, you can do this:
FILES=${/etc/config/iptables*}btw, Ilove the ${FILES%% *} trick. I didn't know about it. The shell is quite nifty.
-pablo
Thanks. That makes sense, i.e., unexpanded assignment. By the way, if I try FILES=${/iptables*}, I get:
./testbash2: line 2: ${testb*}: bad substitution
But, at least I know how to make it work and understand why the first approach failed - John
Signature · 7 lines
John A. Sullivan III Open Source Development Corporation +1 207-985-7880 [email protected] Financially sustainable open source development http://www.opensourcedevel.com
Quoted 9 lines
-----Original Message-----
From: John A. Sullivan III [mailto:[email protected]]
Sent: Monday, February 13, 2006 11:56 AM
To: [email protected]
Cc: Netfilter users list
Subject: RE: [OT] Strange bash phenomenon
Quoted 7 lines
By the way, if
I try FILES=${/iptables*}, I get:./testbash2: line 2: ${testb*}: bad substitution
But, at least I know how to make it work and understand why the first approach failed
Hi John,
The 'bad substition' error originates because there are no files which match the expression.
Given you're looking at trying to determine whether a directory has files you could either do it the way you've initially written up your code or use 'find'
The possible 'issue' with the original 'cp *' is if there was a boatload of files in the directory, you could get a shell expansion error. Probably very unlikely.
One way to handle the corner case is to use find - see the execdir/exec option.
Cheers,
---
Pablo Sanchez - Blueoak Database Engineering, Inc
Ph: 819.459.1926 Toll free: 888.459.1926 Cell: 819.918.9731 Pgr: [email protected] Fax: 603.720.7723 (US) Fax: 514.371.1255 (Canada)