shell内置命令“shift”的实际用法?

shell内置命令“shift”的实际用法?

我检查了shell 脚本/usr/bin/ssh-copy-idopenssh-client至少在 Debian 下是包的一部分),它包含以下 if 语句:

if [ "-i" = "$1" ]; then
  shift
  # check if we have 2 parameters left, if so the first is the new ID file
  if [ -n "$2" ]; then
    if expr "$1" : ".*\.pub" > /dev/null ; then
      ID_FILE="$1"
    else
      ID_FILE="$1.pub"
    fi
    shift         # and this should leave $1 as the target name
  fi
else

命令的要点是什么shift?我的意思是我知道shift nshell 内置函数将n参数数量从左向右移动,但是在此脚本中使用它的原因是什么?为什么不使用:

if [ "-i" = "$1" ]; then
  if [ -n "$3" ]; then
    if expr "$2" : ".*\.pub" > /dev/null ; then
      ID_FILE="$2"
    else
      ID_FILE="$2.pub"
    fi
  fi

答案1

解析完-i选项后你会做什么?还有更多参数需要解析。如果-i是第一个参数,那么在处理完它之后,您需要查看第三个参数。在ssh-copy-id您正在查看的旧版本中,-i是唯一的选项,后面的参数是目标主机名。如果-i未传递,则目标主机名是第一个参数。

if [ "$1" = "-i" ]; then
  target_host_name=$3
else
  target_host_name=$1
fi

当有多个选项时,这不会扩展。您需要跟踪参数列表中的当前位置。

if [ "${$position}" = "-i" ]; then
  position=$((position+2))
fi
target_host_name=${$position}

问题是,我在这里写的不是有效的 shell 语法。没有简单的构造来获取第 n 个参数;你可以用 来做到这一点eval,但这很尴尬,而且古董 shell 无法处理多位参数数字。

因此,每次处理选项时,都会通过调用 来将其从列表中删除shift。如果选项有参数,请调用shift 2shift再次调用以删除选项参数。然后,在处理每个选项之后,处理的下一个参数始终是$1。这样就更简单了。

if [ "$1" = "-i" ]; then
  shift 2
fi
target_host_name=$1

相关内容