0

Below is the assignment for the bash shell script I'm writing. I'm having a problem with -u information being output even though I am using the -f option. This class is a beginner class, so please bear with me. Would be grateful to have some input on my code. Thanks for taking the time to check this out if you do.

Here is the sample output:

[***@***]$ chk3 -f share

share is a directory and it is readable | writable | executable | abecker is currently logged in their home directory is /students/abecker

Here is the usage

chk -f filepath
  • If filepath exists, output in readable sentences
  • if it is a symbolic link, say so. You do not have to continue and report the permissions.
  • if it doesn't exist, say so. Don't continue to report the permissions
  • report what it is: file, directory, or something else, and continue to report the permissions:
  • report what combination of read, write and execute access rights your program has for the data. Note that this is dependent on who runs your program. Do not attempt to do this by looking at the permissions as output by ls -l. You must use the test operators to do this.
  • If filepath does not exist (and is not a symbolic link), your program should report this instead in an informative error message. In this case, you should exit with an error.
chk -u user
  • If the user exists on the system, report
  • the path to the user's home directory
  • if the user is currently logged in, say so. Otherwise, report when they last logged in. (Take some care so that this is generated reliably and quickly.)
  • If the user doesn't exist, report this in an informative error message, and exit with an error.

Here is my code

#!/bin/bash
if [ $# -gt 2 ]
then
  echo "only 2 aruments can be used"
  exit 1
fi
if [ "$1" != '-f' -a "$1" != '-u' ]
then
  echo "first argument must be -f or -u"
  exit 1
fi
if [ "$1" = '-f' -a $# -ne 2 ]
then
  echo 'Usage: chk -f [FILEPATH]'
  exit 1
fi
if [ "$1" = '-f' ]
then
  FILEPATH=$2
fi
if [ -L "$FILEPATH" ]
then
  echo  "$FILEPATH is a symbolic link"
  exit 0
elif  [ -d "$FILEPATH" ]
then
  echo -e "$(basename "$FILEPATH") is a directory and it is \c"
elif [ -f "$FILEPATH" ]
then
  echo -e "$(basename "$FILEPATH") is a file and it is \c"
else
  echo "I cannot determine what $(basename "$FILEPATH") is"
  exit 1
fi
if [ -r "$FILEPATH" ]
then
  echo -e "readable | \c"
fi
if [ -w "$FILEPATH" ]
then
  echo -e "writable | \c"
fi
if [ -x "$FILEPATH" ]
then
  echo -e "executable | \c"
fi
if [ "$1" = '-u' -a $# -eq 1 ]
then
  USER=$LOGNAME
elif [ "$1" = '-u' -a $# -eq 2 ]
then
  USER=$2
fi
USERINFO=$(grep "^$USER:" /etc/passwd)
if ! grep "^$USER:" /etc/passwd > /dev/null
then
  echo "$USER cannot be found on this system"
  exit 1
fi
if ! who | grep "^$USER " > /dev/null
then
  echo "$USER is not currently logged on and last logged on"
  echo "$(last -1 "$USER")"
  exit 0
else
  echo "$USER is currently logged in their home directory is"
  echo "$(echo "$USERINFO" | awk -F":" '{print $6}')"
fi
4

1 回答 1

1

您不会将不同选项的处理放入不同的块中;代码只是通过所有选项的所有内容。

例如,对于-f选项,您有:

if [ "$1" = '-f' ]
then
  FILEPATH=$2
fi

然后处理文件路径的所有选项,而不将它们放入 if 语句中,因此如果您传入其中一个-for -u,它总是会传入代码中:

if [ -L "$FILEPATH" ]
then
  echo  "$FILEPATH is a symbolic link"
  exit 0
elif

如果您不想将程序分解为函数,您要做的是将与处理-f选项相关的所有代码放入同一个 if 语句中,有点像:

if [ "$1" = '-f' ]
then
  FILEPATH=$2
  if [ -L "$FILEPATH" ]
  then
    echo  "$FILEPATH is a symbolic link"
    exit 0
  elif  [ -d "$FILEPATH" ]
  then
    echo -e "$(basename "$FILEPATH") is a directory and it is \c"
  elif [ -f "$FILEPATH" ]
  then
    echo -e "$(basename "$FILEPATH") is a file and it is \c"
  else
    echo "I cannot determine what $(basename "$FILEPATH") is"
    exit 1
  fi
  if [ -r "$FILEPATH" ]
  then
    echo -e "readable | \c"
  fi
  if [ -w "$FILEPATH" ]
  then
    echo -e "writable | \c"
  fi
  if [ -x "$FILEPATH" ]
  then
    echo -e "executable | \c"
  fi
fi # if [ "$1" = '-f' ]

同样对于-u选项,您需要将其分解为多个语句,然后处理该语句的所有选项:

if [ "$1" = 'u' ]
then
  if [ $# -eq 1 ]
  then
    USER=$LOGNAME
  elif [ $# -eq 2 ]
  then
    USER=$2
  fi
  USERINFO=$(grep "^$USER:" /etc/passwd)
  if ! grep "^$USER:" /etc/passwd > /dev/null
  then
    echo "$USER cannot be found on this system"
    exit 1
  fi
  if ! who | grep "^$USER " > /dev/null
  then
    echo "$USER is not currently logged on and last logged on"
    echo "$(last -1 "$USER")"
    exit 0
  else
    echo "$USER is currently logged in their home directory is"
    echo "$(echo "$USERINFO" | awk -F":" '{print $6}')"
  fi
fi # if [ "$1" = '-u' ]

但是,我建议将作用于选项的代码放入 shell 函数中,这样可以更容易阅读代码;例如

filepath() {
  FILEPATH="$1"
  if [ -L "$FILEPATH" ]
  then
    echo  "$FILEPATH is a symbolic link"
    exit 0
  elif  [ -d "$FILEPATH" ]
  then
    echo -e "$(basename "$FILEPATH") is a directory and it is \c"
  elif [ -f "$FILEPATH" ]
  then
    echo -e "$(basename "$FILEPATH") is a file and it is \c"
  else
    echo "I cannot determine what $(basename "$FILEPATH") is"
    exit 1
  fi
  if [ -r "$FILEPATH" ]
  then
    echo -e "readable | \c"
  fi
  if [ -w "$FILEPATH" ]
  then
    echo -e "writable | \c"
  fi
  if [ -x "$FILEPATH" ]
  then
    echo -e "executable | \c"
  fi
}

然后对于处理代码:

if [ "$1" = '-f' ]
then
  filepath "$2"
fi

和选项类似的东西-u

于 2013-04-29T07:42:13.480 回答