Получение последнего аргумента, переданного оболочке script
$1
- первый аргумент.
[email protected]
- все они.
Как я могу найти последний аргумент, переданный оболочке
script?
Ответы
Ответ 1
Это немного взломать:
for last; do true; done
echo $last
Этот тоже довольно портативный (опять же, должен работать с bash, ksh и sh), и он не сдвигает аргументы, что может быть приятным.
Он использует тот факт, что for
неявно перебирает аргументы, если вы не говорите ему, что делать, и тот факт, что для переменных цикла не охвачен: они сохраняют последнее значение, на которое они были установлены.
Ответ 2
Это Bash -одно:
echo "${@: -1}"
Ответ 3
$ set quick brown fox jumps
$ echo ${*: -1:1} # last argument
jumps
$ echo ${*: -1} # or simply
jumps
$ echo ${*: -2:1} # next to last
fox
Пространство необходимо, чтобы оно не интерпретировалось как значение по умолчанию.
Ответ 4
Самый простой ответ для 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
Ответ 5
Используйте индексирование в сочетании с длиной:
echo ${@:${#@}}
Ответ 6
Следующие действия будут работать для вас. @- массив аргументов.: означает at. $# - длина массива аргументов. Таким образом, результатом является последний элемент:
${@:$#}
Пример:
function afunction{
echo ${@:$#}
}
afunction -d -o local 50
#Outputs 50
Ответ 7
Обнаружено это, если вы хотите отделить последний аргумент от всех предыдущих (ей).
Хотя некоторые ответы дают последний аргумент, они не очень помогают, если вам нужны все другие аргументы. Это работает намного лучше:
heads=${@:1:$(($# - 1))}
tail=${@:$#}
Ответ 8
Это работает во всех POSIX-совместимых оболочках:
eval last=\${$#}
Источник: http://www.faqs.org/faqs/unix-faq/faq/part2/section-12.html
Ответ 9
Вот мое решение:
- довольно портативный (все POSIX sh, bash, ksh, zsh) должны работать
- не сдвигает оригинальные аргументы (сдвигает копию).
- не использует
злую eval
- не перебирает весь список
- не использует внешние инструменты
Код:
ntharg() {
shift $1
printf '%s\n' "$1"
}
LAST_ARG='ntharg $# "[email protected]"'
Ответ 10
Если вы используете Bash >= 3.0
echo ${BASH_ARGV[0]}
Ответ 11
Только для bash (начиная с версии 2.01)
$ set -- The quick brown fox jumps over the lazy dog
$ printf '%s\n' "${!#} ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog dog dog dog dog
Для ksh, zsh и bash:
$ echo "${@: -1} ${@:~0}" # the space beetwen ':' and '-1' is a must.
dog dog
А для "рядом с последним":
$ echo "${@:~1:1}"
lazy
Чтобы обойти любые проблемы с аргументами, начинающимися с тире (например, -n
), используйте printf
:
$ printf '%s\n' "${@:~0}"
dog
Для всех оболочек и для более старых sh
(работает с пробелами и символами глобуса):
$ set -- The quick brown fox jumps over the lazy dog "the * last argument"
$ eval echo "\"\${$#}\""
The last * argument
Или, если вы хотите установить переменную last
:
$ eval last=\${$#}; echo "$last"
The last * argument
А для "рядом с последним":
$ eval echo "\"\${$(($#-1))}\""
dog
Ответ 12
Для bash
этот комментарий предложил очень элегантно:
echo "${@:$#}"
В качестве бонуса, это также работает в zsh
.
Ответ 13
shift `expr $# - 1`
echo "$1"
Это сдвигает аргументы на число аргументов минус 1 и возвращает первый (и только) оставшийся аргумент, который будет последним.
Я тестировал только bash, но он должен работать и в sh и ksh.
Ответ 14
Если вы хотите сделать это неразрушающим образом, один из способов - передать все аргументы функции и вернуть последний:
#!/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
Если вы действительно не заботитесь о сохранении других аргументов, вам это не нужно в функции, но мне сложно подумать о ситуации, когда вы никогда не захотите сохранить другие аргументы, если они уже были обработаны, и в этом случае я бы использовал метод process/shift/process/shift/... для последовательной обработки их.
Я предполагаю, что вы хотите сохранить их, потому что вы не следовали последовательному методу. Этот метод также обрабатывает случай, когда нет аргументов, возвращающих "". Вы можете легко отрегулировать это поведение, вставив закомментированное предложение else
.
Ответ 15
Для tcsh:
set X = `echo $* | awk -F " " '{print $NF}'`
somecommand "$X"
Я уверен, что это будет переносное решение, за исключением назначения.
Ответ 16
Решение с использованием eval
:
last=$(eval "echo \$$#")
echo $last
Ответ 17
Прочитав ответы выше, я написал оболочку Q & D script (должен работать на sh и bash) для запуска g++ на 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
Ответ 18
Следующее установит 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
Ответ 19
echo $argv[$#argv]
Теперь мне просто нужно добавить текст, потому что мой ответ был слишком коротким для публикации. Мне нужно добавить текст для редактирования.
Ответ 20
Я нашел ответ @AgileZebra (плюс комментарий @starfry) наиболее полезным, но он устанавливает heads
в скаляр. Массив, вероятно, более полезен:
heads=( "${@:1:$(($# - 1))}" )
tail=${@:${#@}}
Ответ 21
Это часть моей функции копирования:
eval echo $(echo '$'"$#")
Чтобы использовать в скриптах, сделайте следующее:
a=$(eval echo $(echo '$'"$#"))
Объяснение (наиболее вложенное первое):
-
$(echo '$'"$#")
возвращает $[nr]
, где [nr]
- количество параметров. Например. строка $123
(нерасширенная).
-
echo $123
возвращает значение 123-го параметра при оценке.
-
eval
просто расширяет $123
до значения параметра, например. last_arg
. Это интерпретируется как строка и возвращается.
Работает с Bash по состоянию на середину 2015 года.
Ответ 22
#! /bin/sh
next=$1
while [ -n "${next}" ] ; do
last=$next
shift
next=$1
done
echo $last
Ответ 23
Попробуйте ниже script найти последний аргумент
# 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
Спасибо.
Ответ 24
Существует гораздо более сжатый способ сделать это. Аргументы в bash script могут быть перенесены в массив, что упрощает работу с элементами. script ниже всегда будет печатать последний аргумент, переданный script.
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
Ответ 25
Используя расширение параметра (удалить соответствующее начало):
args="[email protected]"
last=${args##* }
Также легко получить все до последнего:
prelast=${args% *}
Ответ 26
Этот формат может работать в Slackware и Cygwin.
"$ {x [@]: (- 1)}", если используется с [email protected], "$ {@: (- 1)}"
Это означает: ${@:( N)}, вернет весь элемент после N индекса (включая N),
-1 - это вечность.
Ответ 27
Это возвращает последний использованный параметр.
$_