2014-02-10 3 views
4

У меня есть небольшая функция в моем bashrc, поэтому я могу запустить скрипт и отправить его по электронной почте, когда он закончится. Код состоит в следующем:bash nohup с двумя командами

run() { 
    [email protected] 
    last="${!#}" 
    rest="${@:1:($#-1)}" 

    (nohup $rest &> $last < /dev/null; mail -s "$rest" "$email" < "$last") & 
} 

функция используется как этот

run ./script.sh arg1 arg2 output 

и это, кажется, работает большую часть времени, но иногда электронная почта не присылают, даже если сценарий закончен , Я подозреваю, что это связано с тем, что я закрываю серверный терминал. В этих случаях сценарий все еще работает из-за nohup, но он не отправляет электронное письмо в конце. Я бы очень признателен за некоторые указатели, чтобы заставить его работать правильно.

+0

'rest =" $ {@: 1: ($ # - 1)} "это плохая идея - вы не можете точно представить вектор аргумента в скаляре, так что это выполняется риск того, что аргументы будут неправильно распределены по строкам, glob-расширен и т. д. Вы можете использовать 'rest = (" $ {@: 1: ($ # - 1)} ")', хотя, а затем развернуть его с помощью ' $ {rest [@]} "(или для однострочной сюжетной строки,' '$ {rest [*]}" '... или, точнее,' printf -v rest_cmd '% q' "$ {rest [@]}" ', а затем использовать' '$ rest_cmd" 'как аргумент mail) –

+0

Спасибо за подсказку, я обязательно изменю это. – skd

ответ

5

Есть несколько способов решить эту проблему, но я думаю, что я рекомендовал бы это:

run() { 
    [email protected] 
    rest="${@:1:($#-1)}" 

    nohup bash -c "$rest < /dev/null 2>&1 | mail -s \"$rest\" \"$email\"" & 
} 

Проблема ваша команда nohup закончилась в точку с запятой после /dev/null и, таким образом, не применяется к mail части. (...) вводит подоболочку, но не является внешней командой, поэтому nohup (...) не будет работать, поэтому требуется bash -c "..." (вы также можете использовать ${SHELL} -c " ..." для дополнительной переносимости, если это важно). Двойные кавычки, которые вам нужно было экранировать, были заключены в другой набор кавычек. Кроме того, временный файл не нужен (если вы не хотите его поддерживать по какой-то причине), если это так, не стесняйтесь возвращать перенаправления и отделяйте команды от ; вместо |). Не требуя выходного файла, вы также можете отказаться от бита rest=... и просто называть его run script.sh arg1 arg2, но если у вас уже есть вызовы на него, распространяемые по всему другому коду, может быть проще оставить этот бит внутри - вам придется рисовать что часть из ...

+0

Спасибо! Я на самом деле пробовал '' nohup (...) '' ', и я действительно был смущен тем, что он не работает! – skd

+0

Выходной файл был полезен для меня, поэтому я изменил свой сценарий на '' nohup bash -c '$ rest &> $ last; mail -s \ "$ rest \" \ "$ email \" <\ "$ last \ "" &>/dev/null/dev/null''' в конце. – skd

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