Чи запускається сценарій оболонки, чи можна передавати певні позиційні параметри, не вводячи їх усі в порядку?


13

Наприклад, якщо у мене скрипт ./foo, який приймає 10 параметрів, я хочу передати лише 8-й параметр. Єдиний спосіб, коли я знаю, як це зробити, це:

./foo '' '' '' '' '' '' '' 'bar'

Чи є простіший / кращий спосіб?


1
Ось чому програми зазвичай використовують параметри, а не позиційні параметри, якщо у вас багато параметрів.
Бармар

Відповіді:


4

Ще один спосіб зробити це - назвати параметр, який потрібно оголосити, а потім зробити так:

{   cat >./foo 
    chmod +x ./foo
    eight=declared ./foo
    eight=declared_and_preferred \
        ./foo 1 2 3 4 5 6 7 8
    ./foo 1 2 3 4 5 6 7 8
    ./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT

ВИХІД

$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default

У наведеному вище прикладі явно оголошена змінна середовища є кращою перед аргументом командного рядка, але аргумент командного рядка використовується, коли змінна середовища порожня або не встановлена. Коли і восьмі позиційні і змінна оточення $eightє порожніми або скинути значення по замовчуванням some_default присвоюються $eight. У будь-якому випадку значення :може бути вилучене з :-або :=операторів, якщо порожні мають бути прийнятними значеннями.

Змінна також $eightможе бути встановлена ​​так:

printf '$eight = %s\n' "${eight:=${8:-some_default}}"

... і попередній рядок повністю пропущений, але я хотів продемонструвати, що оголошення таким чином змінної призводить до постійного значення, і це я зробив у двох командах. У будь-якому випадку $eightвстановлюється кінцеве значення розширення цього складного параметра.

getopts- для надійних сценаріїв - найчастіше це найкращий спосіб керувати параметрами команд . З іншого боку, позиційні параметри майже завжди є найпростішим засобом надійної обробки операндів у сценарії.

Наприклад:

touch file$(seq -ws\ file 100)
./foo *

ВИХІД

$eight = file008

Там ми бачимо лише восьмий операнд, але в моєму тестовому каталозі є 101 з них.


18

Припускаючи, що ви можете змінити сценарій, вам слід розглянути можливість використання необов'язкових параметрів (параметрів) замість необхідних параметрів (аргументів).

Якщо у вас є параметри кожного з перших 7 семи параметрів і вони мають за замовчуванням порожній рядок, ви можете просто зробити:

./foo bar

Якщо ви використовуєте сумісну з POSIX оболонку, ви можете скористатися getoptsутилітою або програмою getopt. bash- як і більшість снарядів - пропонує getoptsяк вбудований. Будь-який спосіб простіше, ніж прокат власного аналізатора командного рядка.

Якщо ви не реалізуєте щось на зразок останнього аргументу X, що не є опцією, це значення для останніх аргументів Y та аргументів параметра XY, ви повинні надати рядки опцій перед кожним із 7 (тепер порожніх) рядків, якщо ви хочете встановити будь-який з них. Це, однак, не є звичайною практикою, зазвичай опція - це завжди параметр і аргумент, аргумент, і порядок опції "вставки" вільний.


5
+1для getopt(s). Позиційні параметри - це сумний час, і цього слід уникати.
HalosGhost
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.