Получение последнего аргумента, переданного в сценарий оболочки - PullRequest
244 голосов
/ 06 декабря 2009

$1 - первый аргумент.
$@ это все из них.

Как мне найти последний аргумент, переданный в оболочку сценарий

Ответы [ 26 ]

4 голосов
/ 12 августа 2018

Для 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:

$ 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
2 голосов
/ 06 декабря 2009

Если вы хотите сделать это неразрушающим способом, один из способов - передать все аргументы функции и вернуть последний:

#!/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.

2 голосов
/ 06 декабря 2009
shift `expr $# - 1`
echo "$1"

Это сдвигает аргументы на количество аргументов минус 1 и возвращает первый (и единственный) оставшийся аргумент, который будет последним.

Я тестировал только в bash, но он также должен работать в sh и ksh.

2 голосов
/ 29 октября 2018

Для bash, этот комментарий предложил очень элегантно:

echo "${@:$#}"

В качестве бонуса, это также работает в zsh.

2 голосов
/ 28 апреля 2014

Для tcsh:

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

Я вполне уверен, что это будет переносимое решение, кроме задания.

1 голос
/ 06 декабря 2009

Решение с использованием eval:

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

echo $last
1 голос
/ 22 января 2013

После прочтения ответов выше я написал сценарий оболочки Q & D (должен работать на 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
1 голос
/ 17 августа 2015

Это часть моей функции копирования:

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

Чтобы использовать в скриптах, сделайте следующее:

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

Пояснение (сначала вложенное):

  1. $(echo '$'"$#") возвращает $[nr], где [nr] - количество параметров. Например. строка $123 (нерасширенная).
  2. echo $123 возвращает значение 123-го параметра при оценке.
  3. eval просто увеличивает $123 до значения параметра, например last_arg. Это интерпретируется как строка и возвращается.

Работает с Bash с середины 2015 года.

1 голос
/ 22 октября 2014

Я нашел ответ @ AgileZebra (плюс комментарий @ starfry) наиболее полезным, но он устанавливает heads в скаляр. Массив, вероятно, более полезен:

heads=( "${@:1:$(($# - 1))}" )
tail=${@:${#@}}
1 голос
/ 24 июля 2014
echo $argv[$#argv]

Теперь мне просто нужно добавить текст, потому что мой ответ был слишком коротким для публикации. Мне нужно добавить больше текста для редактирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...