将最后一个参数传递给shell脚本

时间:2009-12-05 23:58:13

标签: shell arguments

$1是第一个参数 $@就是所有人。

如何找到传递给shell的最后一个参数 脚本?

28 个答案:

答案 0 :(得分:269)

这只是Bash:

echo "${@: -1}"

答案 1 :(得分:159)

这有点像黑客:

for last; do true; done
echo $last

这个也很可移植(再次,应该使用bash,ksh和sh)并且它不会移动参数,这可能很好。

它使用for隐式循环遍历参数的事实,如果你没有告诉它循环什么,以及for循环变量没有作用域的事实:它们保留它们被设置的最后一个值到。

答案 2 :(得分:75)

$ set quick brown fox jumps

$ echo ${*: -1:1} # last argument
jumps

$ echo ${*: -1} # or simply
jumps

$ echo ${*: -2:1} # next to last
fox

空间是必要的,因此它不会被解释为default value

答案 3 :(得分:73)

bash 3.0或更高版本的最简单答案是

_last=${!#}       # *indirect reference* to the $# variable
# or
_last=$BASH_ARGV  # official built-in (but takes more typing :)

就是这样。

$ cat lastarg
#!/bin/bash
# echo the last arg given:
_last=${!#}
echo $_last
_last=$BASH_ARGV
echo $_last
for x; do
   echo $x
done

输出是:

$ lastarg 1 2 3 4 "5 6 7"
5 6 7
5 6 7
1
2
3
4
5 6 7

答案 4 :(得分:27)

使用索引结合长度:

echo ${@:${#@}} 

答案 5 :(得分:24)

以下内容适合您。 @是参数数组。 :意思是。 $#是参数数组的长度。结果是最后一个元素:

${@:$#} 

示例:

function afunction{
    echo ${@:$#} 
}
afunction -d -o local 50
#Outputs 50

答案 6 :(得分:21)

在寻找将最后一个参数与前一个参数分开时找到这个。 虽然有些答案确实得到了最后一个论点,但如果你还需要所有其他的args,它们也没什么帮助。这样做效果更好:

heads=${@:1:$(($# - 1))}
tail=${@:$#}

答案 7 :(得分:18)

这适用于所有与POSIX兼容的shell:

eval last=\${$#}

来源:http://www.faqs.org/faqs/unix-faq/faq/part2/section-12.html

答案 8 :(得分:9)

这是我的解决方案:

  • 非常便携(所有POSIX sh,bash,ksh,zsh)应该可以正常工作
  • 不会移动原始参数(转移副本)。
  • 不使用 evil eval
  • 不会遍历整个列表
  • 不使用外部工具

代码:

ntharg() {
    shift $1
    printf '%s\n' "$1"
}
LAST_ARG=`ntharg $# "$@"`

答案 9 :(得分:8)

如果您使用的是Bash> = 3.0

echo ${BASH_ARGV[0]}

答案 10 :(得分:4)

对于ksh,zsh和bash:

$ set -- The quick brown fox jumps over the lazy dog

$ echo "${@:~0}"
dog

对于“倒数第二个”:

$ echo "${@:~1:1}"
lazy

要解决以破折号开头的参数(如-n)的任何问题,请使用:

$ printf '%s\n' "${@:~0}"
dog

处理sh中的空格和glob字符的正确方法是:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

或者,如果您想设置last var:

$ eval last=\${$#}; echo "$last"
The last * argument

对于“倒数第二个”:

$ eval echo "\"\${$(($#-1))}\""
dog

答案 11 :(得分:2)

对于bashthis comment建议非常优雅:

echo "${@:$#}"

答案 12 :(得分:2)

如果你想以非破坏性的方式做,一种方法是将所有参数传递给一个函数并返回最后一个:

#!/bin/bash

last() {
        if [[ $# -ne 0 ]] ; then
            shift $(expr $# - 1)
            echo "$1"
        #else
            #do something when no arguments
        fi
}

lastvar=$(last "$@")
echo $lastvar
echo "$@"

pax> ./qq.sh 1 2 3 a b
b
1 2 3 a b

如果你实际上没有关心关于保留其他参数,你在功能中不需要它,但我很难想到你永远不想保留它的情况其他参数除非它们已被处理,在这种情况下我会使用顺序处理它们的process / shift / process / shift / ...方法。

我在这里假设您要保留它们,因为没有遵循顺序方法。此方法还处理没有参数的情况,返回“”。您可以通过插入注释掉的else子句轻松调整该行为。

答案 13 :(得分:2)

shift `expr $# - 1`
echo "$1"

这会将参数的数量减去1,并返回第一个(也是唯一的)剩余参数,这将是最后一个。

我只在bash中测试过,但它也应该在sh和ksh中工作。

答案 14 :(得分:2)

对于tcsh:

set X = `echo $* | awk -F " " '{print $NF}'`
somecommand "$X"

我很确定这将是一个可移植的解决方案,除了作业。

答案 15 :(得分:1)

以下内容将LAST设置为最后一个参数而不更改当前环境:

LAST=$({
   shift $(($#-1))
   echo $1
})
echo $LAST

如果不再需要其他参数并且可以将其移位,则可以简化为:

shift $(($#-1))
echo $1

出于便携性原因:

shift $(($#-1));

可以替换为:

shift `expr $# - 1`

我们得到的反引号也替换$()

LAST=`{
   shift \`expr $# - 1\`
   echo $1
}`
echo $LAST

答案 16 :(得分:1)

这是我的复制功能的一部分:

eval echo $(echo '$'"$#")

要在脚本中使用,请执行以下操作:

a=$(eval echo $(echo '$'"$#"))

解释(最先嵌套):

  1. $(echo '$'"$#")返回$[nr],其中[nr]是参数的数量。例如。字符串$123(未展开)。
  2. echo $123在评估时返回123rd参数的值。
  3. eval只需将$123扩展为参数的值,例如last_arg。这被解释为一个字符串并返回。
  4. 2015年中期与Bash合作。

答案 17 :(得分:1)

我发现@ AgileZebra的答案(加上@ starfry的评论)最有用,但它将heads设置为标量。数组可能更有用:

heads=( "${@:1:$(($# - 1))}" )
tail=${@:${#@}}

答案 18 :(得分:1)

echo $argv[$#argv]

现在我只需添加一些文字,因为我的回答太短,无法发布。我需要添加更多文字进行编辑。

答案 19 :(得分:1)

在阅读上面的答案后,我写了一个Q& D shell脚本(应该在sh和bash上工作)在PGM.cpp上运行g ++来生成可执行映像PGM。它假定命令行上的最后一个参数是文件名(.cpp是可选的),所有其他参数都是选项。

#!/bin/sh
if [ $# -lt 1 ]
then
    echo "Usage: `basename $0` [opt] pgm runs g++ to compile pgm[.cpp] into pgm"
    exit 2
fi
OPT=
PGM=
# PGM is the last argument, all others are considered options
for F; do OPT="$OPT $PGM"; PGM=$F; done
DIR=`dirname $PGM`
PGM=`basename $PGM .cpp`
# put -o first so it can be overridden by -o specified in OPT
set -x
g++ -o $DIR/$PGM $OPT $DIR/$PGM.cpp

答案 20 :(得分:1)

使用eval的解决方案:

last=$(eval "echo \$$#")

echo $last

答案 21 :(得分:0)

有一种更简洁的方法可以做到这一点。可以将bash脚本的参数放入数组中,这使得处理元素变得更加简单。下面的脚本将始终打印传递给脚本的最后一个参数。

  argArray=( "$@" )                        # Add all script arguments to argArray
  arrayLength=${#argArray[@]}              # Get the length of the array
  lastArg=$((arrayLength - 1))             # Arrays are zero based, so last arg is -1
  echo ${argArray[$lastArg]}

示例输出

$ ./lastarg.sh 1 2 buckle my shoe
shoe

答案 22 :(得分:0)

尝试使用以下脚本查找最后一个参数

 # cat arguments.sh
 #!/bin/bash
 if [ $# -eq 0 ]
 then
 echo "No Arguments supplied"
 else
 echo $* > .ags
 sed -e 's/ /\n/g' .ags | tac | head -n1 > .ga
 echo "Last Argument is: `cat .ga`"
 fi

输出:

 # ./arguments.sh
 No Arguments supplied

 # ./arguments.sh testing for the last argument value
 Last Argument is: value

感谢。

答案 23 :(得分:0)

#! /bin/sh

next=$1
while [ -n "${next}" ] ; do
  last=$next
  shift
  next=$1
done

echo $last

答案 24 :(得分:0)

使用参数扩展(删除匹配的开头):

args="$@"
last=${args##* }

在最后之前也很容易搞定:

prelast=${args% *}

答案 25 :(得分:0)

要返回最近使用的命令的最后一个参数,请使用特殊参数:

 int temp=arr[i];
 arr[i]=arr[minimumIndex];
 arr[i]=temp;

在这种情况下,如果在调用另一个命令之前在脚本中使用它,它将起作用。

答案 26 :(得分:0)

只需使用!$

$ mkdir folder
$ cd !$ # will run: cd folder

答案 27 :(得分:-1)

这种格式可以在Slackware和Cygwin中使用。

" $ {x [@] :( - 1)}",如果与$ @一起使用," $ {@ :( - 1)}"

意思是:$ {@ :( N)},将返回N索引后的所有元素。(包括N), -1是thelast。