回答
这是一个黑客位的:
for last; do true; done
echo $last
这一个也相当可移植的(同样,应该与bash,ksh和sh一起工作),并且不会改变这些参数d很好。
它使用for
隐含地循环参数的事实,如果您不告诉它什么要循环,并且循环变量没有作用域的事实:它们保留它们设置的最后一个值。
@MichałŠrajer,我认为你的意思是冒号而不是逗号;) – 2013-02-26 08:24:01
它适用于我的Android设备。谢谢! – accuya 2013-09-29 19:15:24
@MichałŠrajer['true'是POSIX的一部分](http://pubs.opengroup.org/onlinepubs/009695399/utilities/true.html)。 – Rufflewind 2015-10-09 05:35:35
#! /bin/sh
next=$1
while [ -n "${next}" ] ; do
last=$next
shift
next=$1
done
echo $last
如果参数是空字符串,这将失败,但将在99.9%的情况下工作。 – Thomas 2009-12-06 00:10:20
如果使用击> = 3.0
echo ${BASH_ARGV[0]}
对于接近最后一个参数,执行'echo $ {BASH_ARGV [1]}' – 2012-02-22 02:43:49
shift `expr $# - 1`
echo "$1"
此通过的参数减1的数目移位的参数,并返回第一个(只)剩余的参数,这将是最后一个。
我只在bash中测试过,但它也应该在sh和ksh中工作。
'shift $(($# - 1))' - 不需要外部工具。在Bash,ksh,zsh和短跑中工作。 – 2010-11-09 02:32:45
@丹尼斯:太棒了!我不知道'$((...))'语法。 – 2010-11-11 16:48:54
为了避免'echo'(例如'-n')出现意外行为,您希望使用'printf'%s \ n'“$ 1”'。 – joki 2018-01-04 09:39:47
如果你想要做一个非破坏性的方式,一种方式是将所有参数传递给一个函数,返回最后一个:
#!/bin/bash
last() {
if [[ $# -ne 0 ]] ; then
shift $(expr $# - 1)
echo "$1"
#else
#do something when no arguments
fi
}
lastvar=$(last "[email protected]")
echo $lastvar
echo "[email protected]"
pax> ./qq.sh 1 2 3 a b
b
1 2 3 a b
如果你实际上并不护理关于保留其他参数,你不需要它在一个函数中,但我很难想到一种情况,你永远不想保留其他参数,除非它们已经被处理,在这种情况下,我会使用按顺序处理它们的过程/移位/过程/移位/ ...方法。
我在这里假设你想保留它们,因为你的还没有遵循顺序方法。这个方法也处理没有参数的情况,返回“”。您可以通过插入注释掉的else
子句轻松调整该行为。
使用索引与长度相结合:
echo ${@:${#@}}
只适用于Bash,但一个很好的答案 – 2009-12-06 00:15:24
也适用于ksh。 – 2010-11-09 02:29:04
较短:'echo $ {@:$#}' – 2011-02-28 14:44:32
的溶液使用eval
:
last=$(eval "echo \$$#")
echo $last
对于间接引用的eval是过度杀毒,更不用说不好的做法了,并且存在一个巨大的安全问题(该值不是在echo或$()之外的引用)Bash具有内置语法,用于间接引用,对于任何var:'!'So 'last =“$ {!#}”'会以更安全,紧凑,内在,理智的方式使用相同的方法($#上的间接引用),并且正确引用 – MestreLion 2011-08-07 16:28:28
查看更清晰的方式在[另一个答案](http://stackoverflow.com/a/8868871/2157640) – Palec 2014-10-17 11:23:23
对于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
'$ BASH_ARGV'在bash函数中不起作用(除非我做错了什么)。 – 2014-12-28 15:46:16
看向最后一个参数从所有以前的一个(或多个)分开时,发现这一点。 虽然有些答案确实得到了最后一个参数,但如果您还需要所有其他参数,它们也没什么帮助。这个效果要好得多:
heads=${@:1:$(($# - 1))}
tail=${@:$#}
[Steven Penny的回答](http://stackoverflow.com/a/11217798/938111)更好一些:使用'$ {@:-1}'为* last *和'$ {@:-2: 1}'倒数第二*(等等...)。例如:'bash -c'echo $ {@:-1}'prog 0 1 2 3 4 5 6''打印'6'。要继续使用目前的AgileZebra方法,请使用'$ {@:$# - 1:1}'获取*倒数第二*。例如:'bash -c'echo $ {@:$# - 1:1}'prog 0 1 2 3 4 5 6''打印'5'。 (和'$ {@:$# - 2:1}'得到*倒数*等等......) – olibre 2015-11-26 08:05:53
AgileZebra的答案提供了一种获得*除最后*参数外的所有方法,所以我不会说史蒂文的回答取代它。但是,似乎没有理由使用'$((...))'来减去1,您可以简单地使用'$ {@:1:$# - 1}'。 – dkasak 2016-11-04 20:02:08
请参阅[此评论](http://stackoverflow.com/questions/1853946/getting-the-last-argument-passed-to-a-shell-script/1854031#comment8318885_1853991)附加到旧的相同的答案。 – 2012-07-13 12:21:28
我在这里看到的最简单的便携式解决方案。这个没有安全问题,@DennisWilliamson,除非有一种方法可以将'$#'设置为一个任意字符串(我不这么认为),否则引用经验似乎是正确的。 'eval last = \“\ $ {$#} \”'也起作用,显然是正确的。不明白为什么不需要引号。 – Palec 2014-10-17 11:47:52
对于[tag:bash],[tag:zsh],[tag:dash]和[tag:ksh]'eval last = \“\ $ {$#} \”'很好。但对于[tag:csh]和[tag:tcsh],使用'eval set last = \“\ $ {$#} \”'。看到这个例子:'tcsh -c'eval set last = \“\ $ {$#} \”; echo“$ last”'arg1 arg2 arg3'。 – olibre 2017-07-22 21:11:20
$ 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。
最佳答案,因为它还包括倒数第二个参数。谢谢! – e40 2013-07-07 00:54:55
史蒂文,我不知道你在罚球箱上的表现如何,但我热爱你在这里的工作。 – 2017-09-22 15:09:01
阅读上述我写的Q- & d外壳脚本中的应答后(应在工作sh和bash)的上PGM.cpp运行克++,以产生可执行映像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
这里是我的解决方案:
- 漂亮的便携式(所有POSIX SH时,bash和ksh,zsh中)应该工作
- 不移位原始参数(移动副本)。
- 不使用
邪恶eval
- 不通过整个列表迭代
- 不使用外部工具
代码:
ntharg() {
shift $1
printf '%s\n' "$1"
}
LAST_ARG=`ntharg $# "[email protected]"`
很好的答案 - 简短,便携,安全。谢谢! – 2016-10-07 09:45:37
这是一个好主意,但我有几点建议:首先应该在''1“'和''$#'''周围添加引号”(请参阅https://unix.stackexchange.com/a/171347)。其次,'echo'可悲的是不可移植的(特别是'-n'),所以应该使用'printf'%s \ n'“$ 1”'来代替。 – joki 2018-01-04 09:37:29
谢谢@joki我与很多不同的unix系统一起工作,我也不信任'echo -n',但是我不知道任何posix系统中echo $ 1“'会失败。无论如何,'printf'确实是更可预测的 - 更新。 – 2018-01-09 14:11:36
下面我们来设置LAST
持续不改变当前环境的说法:
LAST=$({
shift $(($#-1))
echo $1
})
echo $LAST
如果不再需要的其他参数和可以移动,可以简化为:
shift $(($#-1))
echo $1
对于便携性的原因如下:
shift `expr $# - 1`
:
shift $(($#-1));
可以替换
更换$()
带反引号我们得到:
LAST=`{
shift \`expr $# - 1\`
echo $1
}`
echo $LAST
尝试下面的脚本来找到最后一个参数
# 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
感谢。
对于tcsh:
set X = `echo $* | awk -F " " '{print $NF}'`
somecommand "$X"
我确信这将是一个便携式解决方案,除了分配。
我知道你永远发布了这个,但这个解决方案非常棒 - 很高兴有人发布了tcsh! – user3295674 2015-02-26 15:30:26
echo $argv[$#argv]
现在我只需要添加一些文字,因为我的回答太短而无法发布。我需要添加更多文本才能编辑。
这是哪个外壳可以工作?不bash。不是鱼(具有'$ argv',但不是'$#argv' - '$ argv [(count $ argv)]'适用于鱼类)。 – 2014-12-16 16:02:09
啊,这在[t] csh中有效。 – 2014-12-16 16:17:04
有一个更简洁的方法来做到这一点。 bash脚本的参数可以放入一个数组中,这使得处理元素变得更加简单。下面的脚本将始终打印传递给脚本的最后一个参数。
argArray=("[email protected]") # 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
我发现@ AgileZebra的回答(加上@ starfry的评论)是最有用的,但它设置heads
一个标。数组可能是更有益的:
heads=("${@:1:$(($# - 1))}")
tail=${@:${#@}}
这仅仅是bash – josch 2015-02-15 07:48:39
这可以格式的Slackware和Cygwin工作。
“$ {X [@]:( - 1)}”,如果与$ @, “$ {@:( - 1)}” 中使用
它的意思是:$ {@ :(Ñ )},将返回N索引后的所有元素。(包括N), -1是最后的。
这是我的复制功能的一部分:
eval echo $(echo '$'"$#")
要在脚本中使用,这样做:
a=$(eval echo $(echo '$'"$#"))
解释(最嵌套在前):
$(echo '$'"$#")
回报$[nr]
其中[nr]
是参数的数量。例如。字符串$123
(未展开)。echo $123
在计算时返回123rd参数的值。eval
只是将$123
扩展为参数的值,例如,last_arg
。这被解释为一个字符串并返回。
工程与bash作为2015年
eval方法已经在这里多次介绍过了,但是这个方法已经解释了它的工作原理。可以进一步改进,但仍值得保留。 – Palec 2015-08-18 23:17:12
下面中旬会为你工作。 @是用于参数数组的。 :意思是。 $#是参数数组的长度。所以结果是最后一个元素:
${@:$#}
例子:
function afunction{
echo ${@:$#}
}
afunction -d -o local 50
#Outputs 50
虽然这个例子是针对一个函数的,但脚本的工作方式也是一样的。我喜欢这个答案,因为它很清晰和简洁。 – 2017-10-03 03:43:29
而且这不是哈克。它使用语言的显式特征,而不是副作用或特殊问题。这应该是被接受的答案。 – musicin3d 2018-01-05 16:09:16
- 1. 传递给shell脚本的检查参数是一个URL
- 2. 调试时,作为参数传递给另一个shell脚本
- 3. 传递两个参数到shell脚本
- 4. 如何获取最后一个参数并在shell脚本中的最后一个参数之前停止?
- 5. 从IDL脚本将参数传递给shell脚本
- 6. 如何获取shell脚本中最后一次递增的值?
- 7. 将第二个参数从shell脚本传递给Java
- 8. shell脚本传递参数的子集
- 9. 如何将参数传递给一个python脚本当我将它传递给一个Django shell
- 10. 从Shell脚本传递参数到Python
- 11. 如何传递参数到shell脚本
- 12. posix_spawn一个shell脚本,传递参数的麻烦
- 13. 将参数传递给来自C#进程的shell脚本
- 14. 将参数传递给来自Python的shell脚本
- 15. 通过shell脚本将引用的参数传递给节点?
- 16. 在Windows Shell中传递给perl脚本的转义参数
- 17. 作为参数传递给shell脚本的命令
- 18. 如何将这些参数之一作为参数传递给此shell脚本
- 19. 传递一个明星参数shell脚本文件
- 20. 将参数传递给包含来自Shell脚本的ACCEPT的SQL * Plus脚本
- 21. 将参数传递给另一个脚本中的函数?
- 22. 如何提供一个文件名作为参数传递给shell脚本
- 23. 如何将shell脚本参数传递给oozie
- 24. 如何将密码作为参数传递给shell脚本
- 25. 如何将命令行参数传递给spark-shell scala脚本?
- 26. 如何使用shell脚本将参数传递给java代码
- 27. shell脚本将表名作为参数传递给sqlplus?
- 28. 将命令行参数传递给shell脚本不起作用
- 29. 如何在脚本中将值列表传递给shell参数
- 30. Bourne Shell脚本打印出最后一个参数
我使用bash,但更便携的解决方案更好。 – Thomas 2009-12-06 00:21:29
http://www.faqs.org/faqs/unix-faq/faq/part2/section-12.html – Inshallah 2009-12-06 02:11:39
使用还可以使用$ {!#} – 2015-10-06 11:43:36