回答
這是一個黑客位的:
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腳本
- 2. 傳遞給shell腳本的檢查參數是一個URL
- 3. 調試時,作爲參數傳遞給另一個shell腳本
- 4. 將shell腳本的參數傳遞給jython腳本
- 5. 傳遞兩個參數到shell腳本
- 6. 如何獲取最後一個參數並在shell腳本中的最後一個參數之前停止?
- 7. 從IDL腳本將參數傳遞給shell腳本
- 8. 如何獲取shell腳本中最後一次遞增的值?
- 9. 將一個shell腳本的所有參數傳遞給另一個
- 10. 將第二個參數從shell腳本傳遞給Java
- 11. 傳遞參數的shell腳本命令
- 12. shell腳本傳遞參數的子集
- 13. 如何查找從$ @中傳遞給腳本的最後一個參數?
- 14. 多個參數傳遞給bash腳本
- 15. 如何將參數傳遞給一個python腳本當我將它傳遞給一個Django shell
- 16. shell腳本:這是傳遞給函數
- 17. 如何傳遞參數到shell腳本
- 18. 從Shell腳本傳遞參數到Python
- 19. 將參數$ {1}傳遞給shell腳本中的一個變量內的shell腳本
- 20. posix_spawn一個shell腳本,傳遞參數的麻煩
- 21. 編寫一個嵌套的shell腳本 - 無法傳遞參數
- 22. 作爲參數傳遞給shell腳本的命令
- 23. 將參數傳遞給來自C#進程的shell腳本
- 24. 將參數傳遞給來自Python的shell腳本
- 25. 通過shell腳本將引用的參數傳遞給節點?
- 26. 將命令行參數傳遞給V8中的腳本JavaScript shell
- 27. 在Windows Shell中傳遞給perl腳本的轉義參數
- 28. 將參數傳遞給要在ssh內執行的shell腳本
- 29. 如何將這些參數之一作爲參數傳遞給此shell腳本
- 30. 傳遞一個明星參數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