Я немного застрял. Моя задача - напечатать аргументы моего сценария в обратном порядке, кроме третьего и четвертого.
Что у меня есть этот код:
#!/bin/bash
i=$#
for arg in "$@"
do
case $i
in
3) ;;
4) ;;
*) eval echo "$i. Parameter: \$$i";;
esac
i=`expr $i - 1`
done
Поскольку я ненавижу eval (привет PHP), я ищу решение без него, но не могу найти его.
Как я могу определить положение аргумента динамически?
PS: Нет, это не домашняя работа, я изучаю оболочку для экзамена, поэтому я пытаюсь решить старые экзамены.
источник
arg
поскольку они заказаны правильно, а не в обратном порядке. Для использованияexpr
я ограничен в использовании только стандарта.#!/bin/bash
, вы можете использовать${!i}
и(())
. Если вы хотите придерживаться стандартного sh, они недоступны, но$((…))
есть.eval
это не единственный портативный способ , как Райан показал .Я держу скрипт
reverse
на моем пути, который делает это:Пример использования:
Вы также можете использовать функцию вместо выделенного скрипта.
источник
$#
? Может ли это быть что-то кроме неотрицательного целого числа?local arg=$1
Это правильное и неопасное использование eval. Вы полностью контролируете контент, который вы используете
eval
.Если это все еще вызывает у вас плохие чувства, тогда, если вас не волнует переносимость, вы можете использовать
${!i}
синтаксис косвенного обращения Bash .источник
${!i}
не входит ли в стандартный синтаксис?Предполагая, что позиционные параметры не содержат символов новой строки:
Тестовое задание:
Тестовый вывод:
источник
С
zsh
:Oa
является флагом раскрытия параметров для сортировки элементов массива при расширении по обратным индексам массива.Исключить 3 и 4:
источник
С практически любой оболочкой:
И вам не нужно использовать подоболочки. Например:
... печать ...
А вот функция оболочки, которая может установить
alias
для вас оболочку , которая будет печатать аргументы вперед или назад:Он не пытается сохранить литеральные значения для каких-либо аргументов, скорее он помещает строку, подобную этой, в
args
alias
:... и сохраняет только ссылки на параметры в прямом и обратном направлении. Он будет хранить до количества, указанного в качестве аргумента. И так выше
alias
было сгенерировано как:printf
Поведение зависит от возвращаемого значения предыдущей команды, которая всегда:
является пустой командой, и поэтому обычно имеет значение true.printf
будет пропускать половину своих аргументов каждый раз, когда он печатает, что по умолчанию выводит аргументы с наименьшего номера на самый большой. Однако, если вы просто делаете:... он печатает их в обратном порядке.
Поскольку псевдоним не хранит никаких литеральных значений, его значение остается статическим, в то время как фактические аргументы могут измениться, но он все равно будет ссылаться на столько, сколько мог бы. Например:
... который печатает ...
Но сброс псевдонима можно сделать так:
... и так печатает ...
источник
источник
for ((i = $# - 1; i >= 0; i--))