2015-04-20 3 views
0

я следующий код:Подскажите в Баш скрипт не показывает параметры

#!/bin/sh 

g_yes=0 
g_no=-1 
g_cancel=1 
g_none=127 

show_yes_no_prompt() 
{ 
     rc=$g_none 
     prompt=$* 
     while true; do 
       read -p $prompt"(ync): " 
       case $yn in 
         [Yy]*) rc=$g_yes; break;; 
         [Nn]*) rc=$g_no; break;; 
         [Cc]*) rc=$g_cancel; break;; 
         *) echo "Please answer yes/no/cancel.";; 
       esac 
     done 
     return $rc 
} 

install_pkg() 
{ 
     pkg_name=$* 
     prompt="Install "$pkg_name"?" 
     show_yes_no_prompt $prompt 
     if [ $? -eq $g_cancel ]; then 
       exit 0 
     fi 
     if [ $? -eq $g_yes ]; then 
       apt-get install -y $pkg_name 
     else 
       echo "Installation of "$pkg_name" refused."  
     fi 
} 

Когда я пишу install_pkg package1 package2 подсказка показывает только «Install», но мне нужно приглашение, чтобы быть как «Установить пакет1 упаковка2 '. Тогда что не так с этим кодом?

+1

Откуда вы вызываете функцию 'install_pkg'? –

+0

Из того же файла сценария. –

+0

Вы используете 'bash'; hashbang должен быть '#!/bin/bash', а не' #!/bin/sh'. – chepner

ответ

1

Ваше цитирование вещей все запутано. Вы хотите процитировать переменные разложения.

Итак, вы хотите prompt="Install $pkg_name?" и show_yes_no_prompt "$prompt" и т. Д. Вместо prompt="Install "$pkg_name"?" и show_yes_no_prompt $prompt.

То, что здесь происходит, что вы передаете каждое слово $prompt в качестве отдельного аргумента show_yes_no_prompt (это хорошо иш при условии, что вы вставляете их все вместе с $* в функции, хотя заметьте, что вы не можете справиться пакеты с пробелы в имени правильно таким образом).

Проблема тогда, когда вы используете $prompt в функции вы не процитировать его, и он разбивается снова и так read «s -p аргумент видит только первое слово и показать, что все это показывает (и затем получает путать ваши «имена переменных» после того, что с pkg(ync) не является допустимым идентификатором.

Вы также не дают yn читать в качестве аргумента, чтобы он не присвоит значение, которое она читает там.

Скорректированная версия сценария ниже.

#!/bin/sh 

g_yes=0 
g_no=-1 
g_cancel=1 
g_none=127 

show_yes_no_prompt() 
{ 
     rc=$g_none 
     while true; do 
       read -r -p "$* (ync): " yn 
       case $yn in 
         [Yy]*) rc=$g_yes; break;; 
         [Nn]*) rc=$g_no; break;; 
         [Cc]*) rc=$g_cancel; break;; 
         *) echo "Please answer yes/no/cancel.";; 
       esac 
     done 
     return $rc 
} 

install_pkg() 
{ 
     pkgs=("[email protected]") 
     show_yes_no_prompt "Install ${pkgs[*]}?" 
     if [ $? -eq $g_cancel ]; then 
       exit 0 
     fi 
     if [ $? -eq $g_yes ]; then 
       apt-get install -y "${pkgs[@]}" 
     else 
       echo "Installation of ${pkgs[*]} refused."  
     fi 
} 

Обратите внимание, как я использовал массив для хранения [email protected] в функции install_pkg. Это единственный способ правильно или безопасно обрабатывать имена пакетов.

Аргумент -r для read - это почти всегда то, что вы хотите, и предотвращает из-за интерпретации/проглатывания обратных косых черт read.

Также отметим, что, в общем, @ разложения являются предпочтительными (и всегда должны быть заключены в кавычки) в * расширений кроме случаев, когда ввод расширения в строке, где одна строка необходима в этом случае * расширение необходимо) ,

Также обратите внимание, что вы никогда не получите -1 от функции. Вместо этого вы получите 255.

1

это неправильная линия:

read -p $prompt"(ync): " 

$prompt содержит пробелы, поэтому read будет принимать только первое слово $prompt. Решение состоит в том, чтобы заключить $prompt в ", поэтому он является цельной строкой.

заменить его

read -p "$prompt (ync): " yn 

В общем, при использовании " строк в Баш, вы можете использовать переменные непосредственно. Нет необходимости разделять строку. Если вы не хотите пробелов, вы можете ограничить имя переменной следующим образом:

read -p "${prompt}(ync): " yn 
+0

Я только что попробовал, и теперь подсказка показывает все аргументы. Но теперь у меня бесконечный цикл! –

+0

Объяснение причин, по которым этот ответ значительно улучшится. –

+0

@Maria_Wang да, то есть, потому что вы не объявляете или не заполняете переменную '$ yn', поэтому ваш оператор case всегда терпит неудачу. См. Мой отредактированный ответ – Slizzered

Смежные вопросы