Получение последнего аргумента, переданного оболочке 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=${@:$#}

Ответ 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

Это возвращает последний использованный параметр.

$_