скрипт не выполняется до конца

Я хотел заменить ifplugd скриптом, демоноподобным скриптом, который будет запускаться при запуске i3. Все работает нормально при запуске с терминала, но всякий раз, когда я пытаюсь автоматически запустить его при запуске, он мгновенно уничтожается.

Команда, которую я использую для запуска при запуске i3:

exec ./.scripts/ifwatch enp0s25>ifwatch.log

Содержимое лог-файла:

[17:00:54]:Setting enp0s25 up
[17:00:55]:Listening on enp0s25

Сам скрипт:

#!/bin/sh
dev=$1
echo [$(date +'%H:%M:%S')]:Setting $dev up
sudo ip link set $dev up
echo [$(date +'%H:%M:%S')]:Listening on $dev
while watch -n 5 -g ip link show dev $dev;
do
    if [[ -n $(ip link show dev $dev |tr '\n' ' ' | grep -v 'NO-CARRIER') ]];
    then
        echo [$(date +'%H:%M:%S')]:$dev "connected! running dhcpcd"
        echo $(sudo dhcpcd $dev)
    else
        echo [$(date +'%H:%M:%S')]:$dev "disconnected! killing dhcpcd"
        echo $(sudo dhcpcd -k $dev)
    fi

done

Я попытался запустить его в экземпляре экрана (из файла i3config), но он даже не создал сокет, я также пробовал не отправлять буфер вывода часов на /dev/null, но это не помогло. Я предполагаю, что процесс мгновенно завершается, потому что при каждом запуске изменяется временная метка файла журнала.


person TMLKyza    schedule 05.08.2019    source источник
comment
Содержимое этого файла журнала не было создано этим сценарием. Покажите соответствующий код и вывод.   -  person Mark Setchell    schedule 05.08.2019
comment
Извините, я не заметил, что файл журнала был из более старой версии кода.   -  person TMLKyza    schedule 05.08.2019
comment
@TMLKyza: Что вы подразумеваете под запуском? Когда компьютер загружается?   -  person user1934428    schedule 05.08.2019
comment
При запуске, как я уже говорил пару раз в вопросе, я имел в виду запуск i3, в основном при загрузке файла конфигурации. Я не имел в виду процедуру загрузки. Более того, i3 запускается через lightdm.   -  person TMLKyza    schedule 05.08.2019
comment
watch запускает программу снова и снова. Когда он когда-нибудь выйдет, чтобы могла произойти внутренняя часть вашего цикла while?   -  person Charles Duffy    schedule 05.08.2019
comment
Другими словами, while foo; do bar; done запускает foo, ждет, пока он завершится, затем запускает bar и возвращается к началу, если foo завершился успешно. watch не завершается ни успешно, ни иначе, поэтому в данном контексте это не имеет смысла.   -  person Charles Duffy    schedule 05.08.2019
comment
watch с параметром -g завершает работу всякий раз, когда изменяется вывод команды   -  person TMLKyza    schedule 05.08.2019
comment
Ах. Действительно ли это происходит на практике, когда вы отслеживаете выполнение своего скрипта? Я не удивлюсь, если watch не работает без телетайпа.   -  person Charles Duffy    schedule 05.08.2019
comment
... во всяком случае, лично, я бы убрал часы из картины и реализовал вашу собственную логику; легче отлаживать, по крайней мере, и больше не зависеть от нестандартного инструмента, который не является ни частью bash, ни POSIX. last_status=$(ip link show dev "$dev"); while :; do new_status=$(ip link show dev "$dev"); if [[ $new_status != "$last_status" ]]; then last_status=$new_status; ...logic here...; fi; sleep 5; done   -  person Charles Duffy    schedule 05.08.2019
comment
... говоря об упрощении отладки, set -x с перенаправлением stderr в файл журнала всегда является хорошей привычкой, когда вы пытаетесь что-то отследить. (То есть: exec 2>/path/to/your.log; set -x, так как вторая строка вашего скрипта сделает след каждой написанной строки, идущей к your.log).   -  person Charles Duffy    schedule 05.08.2019
comment
он работает, если запущен в терминале, я тоже думал о том же, поэтому решил попробовать запустить его из конфигурационного файла i3 в сокете экрана (exec screen ./.scripts/ifwatch enp0s25>ifwatch.log), но он даже не создает   -  person TMLKyza    schedule 05.08.2019
comment
Вы также можете исправить бесполезное использование echo. echo $(thing) - это просто глючный и неэффективный способ сказать thing (если только вы специально не требуете, чтобы оболочка выполняла токенизацию пробелов и расширение подстановочных знаков на выходе из thing).   -  person tripleee    schedule 05.08.2019


Ответы (1)


Как предложил Чарльз Даффи, я написал функцию для выполнения работы watch -g, и теперь она работает отлично. Как он сказал, вероятно, watch не работает вне телетайпа.

Вот код, если кому интересно:

#!/bin/sh
dev=$1
sleeptime=5

function watcher {
    state1=$(ip link show dev $dev) 
    state2=$state1
    while [ "$state1" == "$state2" ];
    do
        sleep $sleeptime
        state2=$(ip link show dev $dev)
    done
    return 0
}


echo [$(date +'%H:%M:%S')]:Setting $dev up
sudo ip link set $dev up
echo [$(date +'%H:%M:%S')]:Listening on $dev
while watcher;
do
    if [[ -n $(ip link show dev $dev |tr '\n' ' ' | grep -v 'NO-CARRIER') ]];
    then
        echo [$(date +'%H:%M:%S')]:$dev "connected! running dhcpcd"
        sudo dhcpcd $dev
    else
        echo [$(date +'%H:%M:%S')]:$dev "disconnected! killing dhcpcd"
        sudo dhcpcd -k $dev
    fi

done
person TMLKyza    schedule 05.08.2019