2015-10-01 6 views
0

Я хочу использовать следующую конструкцию несколько раз в течение моего сценария:Как написать обертку для произвольной команды bash?

tries=0 
while ! resposta=$(ssh ${nodes[$k]} 'nproc && uptime'); do 
    let tries+=1 
    if ((tries > max_tries)); then 
     printf "Can't connect to %s !!!" "${nodes[$k]}" 
     exit 1 
    fi 
    printf "Failed! Trying again after %d seconds...\n" "$sleep_time" 
    sleep $sleep_time 
done 

Этот код запускает resposta=$(ssh ${nodes[$k]} 'nproc && uptime') команду несколько раз, пока он не работает, или до тех пор, пока не достигнет максимального числа попыток.

Однако есть много команд, которые я хотел бы обернуть внутри блока, подобного выше. То, что я сейчас делаю, это: повторять весь блок каждый раз, когда я этого хочу, изменяя команду, которая составляет условие цикла while.

Это, конечно, буйство и глупость. Хотелось бы избежать решений на основе eval, хотя - по той же причине, что eval является злым, кроме того, что нарушает синтаксис-подсветку :)

ответ

2

Вы можете написать функцию, которая принимает команду, которую вы хотите запустить как цитируемый аргумент:

function repeat() { 
    tries=0 
    while ! resposta=$($1); do 
     let tries+=1 
     if ((tries > max_tries)); then 
      printf "Command %s failed" "$1" 
      exit 1 
     fi 
     printf "Failed! Trying again after %d seconds...\n" "$sleep_time" 
     sleep $sleep_time 
    done 
} 

repeat "ssh ${nodes[$k]} ''nproc && uptime''" 

Обратите внимание, что строка котируется, когда передается в, чтобы избежать его интерпретации, но не котируется, когда она расширяется, как $1, так что команда на самом деле вызывается.

Также обратите внимание на удвоенные одинарные кавычки. Это говорит bash использовать фактические символы одиночной кавычки в строке, переданной функции. В противном случае одинарные кавычки будут удалены, и вы получите следующую ошибку с сервера:

bash: nproc & uptime: command not found 
+0

Это не сработает, потому что одинарные кавычки становятся обычными символами. – rici

+2

Вместо использования '$ 1' используйте' '$ @" 'с' repeat ssh '$ {nodes [$ k]} "' nproc && uptime'', но даже тогда' repeat' не сможет принимать произвольные команд оболочки, просто простая команда, состоящая из имени команды и ее аргументов. – chepner

+1

(Это не значит, что это плохая идея, совсем наоборот. Просто написать командную оболочку в оболочке без 'eval'.) – chepner

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