Bash Scripting " [!: not found " errors, and how to write an or statement
Solution 1
Another issue is that at the start of the script you do
files = `ls`
but then you cd to a different directory and try to loop round $files deleting them - of course this will not work since you have changed directories.
move the ls line to after you have changed directory.
Solution 2
You forgot to put a space after [
and before ]
on the line saying:
if [! -d $f]
AND tests are created using -a
, -o
is equal to OR:
if [ ! -d $f -a -f $f ]
if [ ! -d $f -o -f $f ]
Solution 3
Try putting a space between the [
and !
.
Solution 4
I'm augmenting other answers here ... every time I see a bash question start with #! /bin/sh
I have to jump in, its a moral imperative.
Keep in mind that /bin/sh
points to the POSIX invocation of bash, or a completely different "posixically correct" shell like dash. /bin/sh is often a symbolic link that causes bash to alter its behavior to be more POSIX compliant. Hence, lots of goodies won't work as usual, or you may find your code being parsed by another shell.
In other words, /bin/sh == POSIX_ME_HARDER, but .. yikes! ==
is a bashism :)
If you want bash, use #!/bin/bash
Beyond that, singingwolfboy's answer should fix your immediate problem :)
Solution 5
The other answers are correct, here's why: [ is a command. If you type "[!", the shell looks for a command by that name.
Related videos on Youtube
에이바
Updated on June 04, 2022Comments
-
에이바 almost 2 years
EDIT: Here is my updated code:
#!/bin/sh files=`ls` if [ $# -ne 1 -o -f $1 ] then echo "Usage: $0 <directory>" exit 1 fi if [ ! -e $1 ] then echo "$1 not found" exit 1 elif [ -d $1 ] then cd $1 for f in $files do if [ ! -d "$f" ] then if [ ! -s "$f" ] then rm -r "$f" echo "File: $f was removed." else continue fi fi done echo "Name\t\tLinks\t\tOwner\t\tDate" for f in $files do find "$f" -type f -printf "%f\t\t %n\t\t %u\t %TH %Tb %TY\n" done exit 0 fi
I fixed all of the spacing issues, changed #!bin/sh to #/bin/bash, and added quotes to "$f". However I'm still getting lots of errors.
ava@kosh:~/test$ ./delDir d1 rm: cannot remove
d1': No such file or directory File: d1 was removed. rm: cannot remove
delDir': No such file or directory File: delDir was removed. rm: cannot removedelDir2': No such file or directory File: delDir2 was removed. rm: cannot remove
e1': No such file or directory File: e1 was removed. rm: cannot removee2': No such file or directory File: e2 was removed. rm: cannot remove
make_d1': No such file or directory File: make_d1 was removed. Name\t\tLinks\t\tOwner\t\tDate find: d1: No such file or directory find: delDir: No such file or directory find: delDir2: No such file or directory find: e1: No such file or directory find: e2: No such file or directory find: make_d1: No such file or directory ne1 2
ava 22 Nov 2009 ne2
2 ava 22 Nov 2009Does anyone know what else I'm doing wrong?
Here's my code:#!/bin/sh files=`ls` if [ $# -ne 1 ] then echo "Usage: $0 <directory>" exit 1 fi if [ ! -e $1 ] then echo "$1 not found" exit 1 elif [ -d $1 ] then cd $1 for f in $files do if [! -d $f] then if [ ! -s $f ] then rm-r $f echo "File: $f was removed." else continue fi fi done echo "Name\t\tLinks\t\tOwner\t\tDate" for f in $files do find $f -type f -printf "%f\t\t %n\t\t %u\t %TH %Tb %TY\n" done exit 0 fi
Here are my questions:
If I execute the script with something that is NOT an ordinary file AND is NOT a directory I want it to say "Usage: Filename directory" (see line 5). I know I can do this with 2 if statements but is it possible to create an or statement for this in bash?
When I run the script I keep getting errors like this:
./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found ./delDir: 39: [!: not found Name
Links Owner Date find: d1: No such file or directory find: delDir: No such file or directory find: delDir2: No such file or directory e1 1
ava 22 Nov 2009 e2
1 ava 22 Nov 2009 find: make_d1: No such file or directory ne1 2
ava 22 Nov 2009 ne2
2 ava 22 Nov 2009I believe I am getting these errors because the for loop is first looking for the file that the user typed in (the directory it changed into) and cannot find it. How can if fix this? 3. Are there any more errors you can see?
-
에이바 over 14 yearsHere's what happens after the spaces have been removed: ava@kosh:~/test$ ./delDir d1 ./delDir: 39: rm-r: not found File: d1 was removed. ./delDir: 39: rm-r: not found File: delDir was removed. ./delDir: 39: rm-r: not found File: delDir2 was removed. ./delDir: 39: rm-r: not found File: e1 was removed. ./delDir: 39: rm-r: not found File: e2 was removed. ./delDir: 39: rm-r: not found File: make_d1 was removed. Name Links Owner Date find: d1: No such file or directory find: delDir: No such file or directory find: delDir2: No such file or directory e1 1
-
George Shore over 14 yearsYou need to add a space between the
rm
and the-r
; bash sees this a commandrm-r
and notrm -r
. -
에이바 over 14 yearsOh I see. Thanks for the tip, I'll have to use that.
-
에이바 over 14 yearsAh... okay I see. I'm trying that now.
-
에이바 over 14 yearsThanks for the info Amrox, I added the quotes as per your suggestion. I'll have to make use of them in the future.