質問

I want to write a script that take 1 command line argument( a directory) and then prompt for 2 number, it will then print out any file(each in a different line) that has the size between that 2 number, this is my script

echo -n "Enter the first number: "
read a
echo -n "Enter the second, bigger number: "
read b
    if
 [ $b -lt $a ]
then
 echo 'The first number must be smaller'
else
 echo The files in $1 that are between $a and $b bytes are the following
 echo
 for var in 'ls $1'
 do
  if
   [ -f $var ]
  then
    size='ls -l $var | '{ print $5 }''
     if
      [ $size -le $b && $size -ge $a ]
     then
      echo $var is $size bytes
     fi
  fi
 done
fi

The problem is after I enter the numbers, it will print out "The files..." and then nothing else. Also, I use Vi to edit it,but the color of last three lines is not quite right(the color should match the first "fi" but it not). Can anyone show me what was wrong? Thank you.

役に立ちましたか?

解決

Your immediate problem is that you used single quotes where you wanted command substitution. However, this is the wrong way to iterate over files. You should use pattern matching instead. Your for loop should read

for var in $1/*
do
  if [ -f "$var" ]
  then
    # Check 'man stat' for the correct format string on your system
    size=$(stat +%s "$var")
    if [ $size -le $b ] &&  [ $size -ge $a ]
    then
      echo $var is $size bytes
    fi
  fi
done

他のヒント

There are a couple of problems here, but the one that I think has you stuck is that the single-quote character (') is used in a couple of places where the backtick character (`) should be used. This is a subtle typographical distinction, so sometimes people that haven't encountered it before don't pick up on the distinction. On my keyboard, you get a backtick character by hitting the key just to the left of the number 1, it is paired with the tilde (~), but your keyboard may be different.

The backtick allows you to assign the output of a command to a variable, for example:

my_variable=`ls - l` # <- uses backtick, assigns output of 'ls -l' command to $my_variable

#As opposed to:
my_variable='ls -l' # <- uses single-quote, makes $my_variable equal to the text "ls -l"

Note, this will also fix your vi issue if you replace the correct single-quotes w/backticks.

As stated by others, use a shebang and use backticks for your commands. Other things that were wrong, ls -l $var | '{ print $5 }' should be ls -l "$1$var" | awk '{ print $5 }' (awk command was missing), and when testing the files you should use the full path to the file like [ -f "$1$var" ] since the user may not be in the same directory as the path they provide as an argument to the script. Another problem is [ $size -le $b && $size -ge $a ]. You can't use the && operator that way, instead use [ $size -le $b ] && [ $size -ge $a ].

These are all the changes I made to your code. Hope it works for you.

echo -n "Enter the first number: "
read a
echo -n "Enter the second, bigger number: "
read b
if [ $b -lt $a ]
then
  echo 'The first number must be smaller'
else
  echo The files in "$1" that are between "$a" and "$b" bytes are the following
  echo
  for var in `ls "$1"`
  do
    if [ -f $1$var ]
    then
      size=`ls -l "$1$var" | awk '{ print $5 }'`
      if [ $size -le $b ] && [ $size -ge $a ]
      then
        echo "$var" is "$size" bytes
      fi
    fi
  done
fi
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top