English 中文(简体)
Bash Scripting " [!: not found " errors, and how to write an or statement
原标题:

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		Links		Owner		Date"

for f in $files
        do
                find "$f" -type f -printf "%f		 %n		 %u	 %TH %Tb %TY
"
        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 removedelDir : No such file or directory File: delDir was removed. rm: cannot remove delDir2 : No such file or directory File: delDir2 was removed. rm: cannot removee1 : No such file or directory File: e1 was removed. rm: cannot remove e2 : No such file or directory File: e2 was removed. rm: cannot removemake_d1 : No such file or directory 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 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 2009

Does 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		Links		Owner		Date"

for f in $files
        do
                find $f -type f -printf "%f		 %n		 %u	 %TH %Tb %TY
"
        done
        exit 0
fi

Here are my questions:

  1. 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?

  2. 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 2009

I 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?

最佳回答

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.

问题回答

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 ]

Try putting a space between the [ and !.

The other answers are correct, here s why: [ is a command. If you type "[!", the shell looks for a command by that name.

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 :)

The others got the spacing issue with the [, but I noticed a couple other things.

You probably need a space in your rm command in line 23:

rm -r $f

Also, it s usually good practice to double quote file paths. This will allow your script to handle filenames with spaces and other special characters correctly.

rm -r "$f"




相关问题
What does it mean "to write a web service"?

I just asked a question about whether it was possible to write a web-page-checking code and run it from free web server, and one supporter answered and said that it was possible only if I run "a web ...

How can I use exit codes to run shell scripts sequentially?

Since cruise control is full of bugs that have wasted my entire week, I have decided the existing shell scripts I have are simpler and thus better. Here is what I have so far svn update /var/www/...

Dynamically building a command in bash

I am construcing a command in bash dynamically. This works fine: COMMAND="java myclass" ${COMMAND} Now I want to dynamically construct a command that redirectes the output: LOG=">> myfile.log ...

Why does Scala create a ~/tmp directory when I run a script?

When I execute a Scala script from the command line, a directory named "tmp" is created in my home directory. It is always empty, so I simply deleted it without any apparent problem. Of course, when I ...

Ivy, ant and start scripts

I have a project that uses ant to build and ivy for dependencies. I would like to generate the start scripts for my project, with the classpath, based on the dependencies configured in Ivy, ...

热门标签