Параметри сценарію в Bash


103

Я намагаюся зробити сценарій оболонки, який слід використовувати так:

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

Потім сценарій ocr перетворить файл зображення в текстовий файл. Ось що я придумав поки що:

#!/bin/bash
export HOME=/home/kristoffer
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1

Але я не знаю , як отримати -fromі -toзначення. Будь-які ідеї, як це зробити?


6
Ви повинні прочитати tldp.org/LDP/Bash-Beginners-Guide/html / ...
Mehul Rathod

Відповіді:


124

Аргументи , які ви надаєте в bashscript з'являться в змінних $1і $2і $3де число відноситься до аргументу. $0- це сама команда.

Аргументи розділені пробілами, тож якщо ви надасте команду -fromі і -toв команді, вони також опиняться в цих змінних, тому для цього:

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

Ви отримаєте:

$0    # ocrscript.sh
$1    # -from
$2    # /home/kristoffer/test.png
$3    # -to
$4    # /home/kristoffer/test.txt

Можливо, буде простіше опустити -fromта -to, як-от:

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt

Тоді у вас буде:

$1    # /home/kristoffer/test.png
$2    # /home/kristoffer/test.txt

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

Тоді ви можете зробити:

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

Подвійні лапки навколо $1та $2не завжди потрібні, але вони вводяться, оскільки деякі рядки не працюватимуть, якщо ви не розмістите їх між подвійними лапками.


69

Якщо ви не повністю прихильні до використання "від" і "до" в якості імен варіантів, реалізувати це досить легко за допомогою getopts :

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done

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

f:t:вказує, що ви очікуєте 2 параметра, які містять значення (вказані двокрапкою). Щось на зразок f:t:vговорить, що -vбуде трактуватися лише як прапор.

optsде зберігається поточний параметр. caseЗаява, де ви будете обробляти це.

${OPTARG}містить значення, яке слідує за параметром. ${FROM_VAL}наприклад, отримає значення, /home/kristoffer/test.pngякщо ви запустили свій сценарій, наприклад:

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

Як говорять інші, якщо ви вперше пишете баш сценарії, вам слід прочитати деякі основи. Це був лише швидкий посібник про те, як getoptsпрацює.


1
Це здається читабельним рішенням. Як ви б тоді вказали два прапори?
Зельфір Кальтшталь

@Zelphir, ви можете вказати два чи більше прапорів, просто опускаючи прапор ":" після прапора. Наприклад, f:t:vsбуде-f some_f -t some_t -v -s
h_s

34

Використовуйте змінні "$1", "$2", "$3"і так далі аргументи доступу. Щоб отримати доступ до всіх них, ви можете використовувати "$@"або отримати кількість аргументів $#(може бути корисно перевірити наявність занадто мало або занадто багато аргументів).


24

Мені потрібно було переконатися, що мої сценарії повністю переносяться між різними машинами, оболонками та навіть версіями cygwin. Далі мої колеги, які мені доводилося писати сценарії, - це програмісти, тому я в кінцевому підсумку користувався цим:

for ((i=1;i<=$#;i++)); 
do

    if [ ${!i} = "-s" ] 
    then ((i++)) 
        var1=${!i};

    elif [ ${!i} = "-log" ];
    then ((i++)) 
        logFile=${!i};  

    elif [ ${!i} = "-x" ];
    then ((i++)) 
        var2=${!i};    

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
        var3=${!i};

    elif [ ${!i} = "-b" ];
    then ((i++)) 
        var4=${!i};

    elif [ ${!i} = "-l" ];
    then ((i++)) 
        var5=${!i}; 

    elif [ ${!i} = "-a" ];
    then ((i++)) 
        var6=${!i};
    fi

done;

Обґрунтування: Я також включав launcher.shсценарій, оскільки вся операція мала кілька кроків, які були незалежно один від одного (я кажу "квазі", тому що, хоча кожен сценарій може бути запущений самостійно, вони, як правило, всі запускаються разом ), і за два дні я дізнався, що близько половини моїх колег, будучи програмістами і всі, були надто хорошими, щоб використовувати файл запуску, дотримуватися "використання" або читати HELP, який відображався кожного разу, коли вони щось робили неправильно, і вони робили безлад у всьому, запускаючи сценарії з аргументами в неправильному порядку і скаржачись, що сценарії не працюють належним чином. Будучи холериком, я вирішив переглянути всі мої сценарії, щоб переконатися, що вони не є колегами. Кодовий сегмент вище був першим ділом.


2
Мені подобається це. Я додаю розділ у кінці `else echo" Недійсний аргумент: $ {! I} "((i ++))
fi`

6

У bash $1перший аргумент передається до сценарію, $2другий тощо

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

Отже, ви можете використовувати:

./your_script.sh some_source_file.png destination_file.txt

Пояснення на подвійні лапки;

розглянути три сценарії:

# foo.sh
bash bar.sh $1

# cat foo2.sh
bash bar.sh "$1"

# bar.sh
echo "1-$1" "2-$2"

Тепер виклик:

$ bash foo.sh "a b"
1-a 2-b

$ bash foo2.sh "a b"
1-a b 2-

Коли ви викликаєте, foo.sh "a b"то він викликає bar.sh a b(два аргументи), і разом з foo2.sh "a b"ним викликає bar.sh "a b"(1 аргумент). Завжди майте на увазі, як параметри передаються та розширюються в баші, це позбавить вас від головного болю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.