2014-01-08 4 views
0

У меня есть этот кусок кодаПолучение команды BASH PID

#!/bin/bash 
streamURL=http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8 

(
    echo "Debugging for stream: $streamURL"; 
    echo "Starting debugging..."; 
    vlc -vvv --color $streamURL --file-caching=10000 2>&1 | sed "s/^/ `date`/"; 

) | tee debug.txt & 
PROCESS_PID=$! 

ps -e | grep $PROCESS_PID 
echo " killing process pid: " 
echo $PROCESS_PID; 
kill -9 $PROCESS_PID 
ps -e | grep vlC#still there 

Моя проблема, я не могу управлять, чтобы сохранить «VLC ...» Команда PID в переменную, чтобы убить его позже. Если я переведу «PROCESS_PID = $!« сразу после него, он будет пустым. Также нужна труба после нее для sed. Какие-либо предложения?

+0

@mbratch в приведенном выше коде, PID, который я получаю, исходит от команды «tee» – Vodaldrien

+1

Почему вы хотите pid? Если вы планируете отправлять сигнал только через определенный промежуток времени, то, вероятно, гораздо проще использовать 'timeout' или поместить команду' vlc' внутри сценария оболочки, которая сделает тайм-аут для вас. –

+0

@WilliamPursell У меня не было знания тайм-аута, так как я нахожусь в начале с bash. спасибо за предложение. Я попробую это – Vodaldrien

ответ

2

Вы можете получить pid с помощью файловых дескрипторов, но это больно. Например:

{ PID=$({ ( 
    echo foo; 
    echo bar; 
    sh -c 'echo $$ >&5; exec echo baz') | 
    tr a o; } 5>&1 1>&3); } 3>&1 

присвоит PID «echo baz» PID. Замените это эхо на vlc и замените tr на sed, и у вас должно быть решение.

Чтобы попытаться дать несколько упрощенное объяснение того, что здесь происходит, сначала обратите внимание, что мы используем замещение процесса, чтобы присвоить значение PID. Синтаксис $() просто берет команду внутри круглых скобок и назначает переменной выход команды. Важно помнить, что здесь «вывод» означает «все, что напечатано в дескрипторе файла 1». Внутри команды sh мы печатаем pid для дескриптора файла 5, а затем exec echo. Используя exec, это эхо имеет тот же pid, что и предыдущее эхо. Теперь эхо foo, bar и baz все записывают в трубу, которая идет в tr. Вывод tr перенаправляется на fd 3 (до редактирования, это был fd 2. Какой дескриптор файла использовать, в основном, произвольный, но изменение 2 - плохая идея в случае возникновения каких-либо ошибок), а файловый дескриптор 5 перенаправляется на fd 1, так что он становится «выходом» подстановки процесса, назначенной PID. Затем вне подстановки процесса мы назначаем fd 3 для вывода, где это было первоначально желательным. Надеюсь, этот параграф более объяснительный, чем запутывание: если вы смущены, посмотрите на код для разъяснения!

К сожалению, это становится уродливой, если вы хотите работать в фоновом режиме:

{ PID=$({ ( 
    echo foo; 
    echo bar; 
    sh -c 'echo $$ >&5; exec 5>&-; exec echo baz' >&3 &) | 
    tr a o; } 5>&1 1>&3); } 3>&1 

Здесь вам нужно закрыть дескриптор файла 5, чтобы гарантировать, что замена процесс завершается.

+0

Ничего себе, голова крутится. У него проблемы с пониманием (bash newbie) ^^ – Vodaldrien

+1

Да, это довольно неясно. Я попытаюсь добавить объяснение, но код действительно говорит сам за себя. –

2

Вы не можете назначить переменную в subshell и get it back outside it.

В этом случае, если вы kill $!, вы убьете tee, который (AFAIK) отправит SIGPIPE на подоболочку и прекратит все это. Поэтому, как правило, нет необходимости в PID в подоболочке.

Я не уверен, но проблема может заключаться в том, что вы - nuking the process from orbit with SIGKILL, а не убиваете его мягко только с kill $PID. Может быть, tee делает не отправьте SIGPIPE в этом случае, потому что он не может очиститься после себя.

Другими словами, просто используйте kill $process_id. Имейте в виду, что убийство процесса не является синхронным - вы просто отправляете ему сигнал и продолжаете. См. Kill bash processes “nicely”.

+0

Просто попробовал, но он, похоже, не работает: я получаю pee te, но убиваю его также не убить vlc – Vodaldrien

+0

Пожалуйста, обновите вопрос с помощью кода, который вы используете, чтобы убить процесс. – l0b0

+0

Что я хочу сделать, это позволить процессу работать около 20 секунд, используя сон, убить его, особенно vlc, и после этого продолжить разбор журнала. Это будет повторяться каждую минуту, поэтому мне действительно нужно очистить корзину :) – Vodaldrien

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