Bash Scripting " [!: not found " errors, and how to write an or statement

12,846

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.

Share:
12,846

Related videos on Youtube

에이바
Author by

에이바

Updated on June 04, 2022

Comments

  • 에이바
    에이바 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 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\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 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\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:

    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?

  • 에이바
    에이바 over 14 years
    Here'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
    George Shore over 14 years
    You need to add a space between the rm and the -r; bash sees this a command rm-r and not rm -r.
  • 에이바
    에이바 over 14 years
    Oh I see. Thanks for the tip, I'll have to use that.
  • 에이바
    에이바 over 14 years
    Ah... okay I see. I'm trying that now.
  • 에이바
    에이바 over 14 years
    Thanks for the info Amrox, I added the quotes as per your suggestion. I'll have to make use of them in the future.

Related