2016-07-09 5 views
0

Я хочу получить PID bash и выделить его, если он находится в каком-то текстовом файле (предположим, что это так). Поэтому, когда я печатаю это в моей оболочке:Как grep pidof bash в сценарии оболочки?

grep -o $(pidof bash) test.txt 

это просто прекрасно работает и дает мне нужный выход, PID Баш. Тогда почему этот сценарий не работает:

#!/bin/bash 
PID=$(grep -o $(pidof bash) test.txt) 
echo $PID 

я получаю только несколько строк с:

Grep: ххх: файл или каталог не найден

ххх являются случайными числами, но обычно последний - тот, который я ищу.

Как достичь этого и почему вышеуказанное не работает?

Как это связано с созданием нового процесса оболочкой при вызове grep в скрипте?

спасибо.

+1

«$ BASH_PID» - это подходящий инструмент для использования, или '$$' (в зависимости от того, какой именно PID оболочки вам нужен - родительская оболочка или подоболочка, начинающаяся с '$()'). –

+0

... 'pidof' - это, вообще говоря, инструмент, который лучше всего избегать, если вы не найдете лучшего способа определить конкретный процесс - любая система будет иметь * lots * экземпляров bash, запущенных в любой момент времени. –

ответ

1

Когда вы запускаете pidof внутри вашего сценария оболочки, есть как минимум два экземпляра bash, поэтому он будет возвращать несколько номеров. Способ grep разработан, он может искать только один шаблон за раз, поэтому первое число интерпретируется как шаблон, а другие числа ошибочно интерпретируются как имена файлов или каталогов.

Я не уверен, Баш PID вы заботитесь о, но одно решение использовать что-то вроде grep, head или tail фильтровать вывод pidof так что вы просто получите один номер. Другим решением является использование специальной переменной $$, которая представляет собой PID экземпляра bash, который его оценивает.

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

echo grep -o $(pidof bash) test.txt 
+0

'$$' не * довольно * то, что вы его описываете, - если у вас есть подоболочка, '$$' расширяется до PID родительской оболочки, так что вы действительно хотите '$ BASH_PID' вместо этого, если цель для определения этой подоболочки. –

+0

Кроме того, 'echo' - отличный инструмент. Я бы предложил 'printf '% q' grep -o $ (pidof bash) test.txt; echo' - таким образом вы передаете вещи буквально, так что 'printf '% q' grep -o" $ (pidof bash) "test.txt; echo' будет выглядеть по-другому, тогда как с помощью 'echo' фиксация кавычек (в то время как это сильно изменяет фактическое поведение) не оказывает заметного влияния на выход. –

+0

'set -x' - еще одна предпочтительная альтернатива, немного менее подробная, чем весь' printf% q'. 'set -x' поместит оболочку в режим отладки, где она будет печатать каждую команду перед ее исполнением до тех пор, пока она не будет отключена с помощью' set -x', и выведет ее * таким образом, чтобы сделать цитирование, пробел и другое содержимое, 'echo' explicit *. –

1

У меня нет pidof, поэтому я предполагаю, что это эквивалент pgrep -v, распечатывая список PID, по одному на каждой строке, с новой линией между ними.

Если это так, подумайте:

egrep -o "$(pgrep -v bash | tr '\n' '|')" test.txt 

Предположим, что выход pgrep -v bash является:

123 
456 
789 

Ваш исходный код будет сделать это:

egrep -o 123 456 789 test.txt 

... таким образом, поиск 123 в файле с именем 456, в файл с именем 789 и в файле с именем test.txt.


Теперь сравните с тем, что происходит, когда вы заменить этот пробел с символами трубы:

egrep -o "123|456|789" test.txt 

... исполненный по трубопроводу предложил ранее в этом вопросе именно то, что вы искали. (BTW, цитаты здесь чисто синтаксические - то есть они предназначены для потребления оболочкой, когда они понимают, как вещи разбираются, а не передаются egrep).


Это говорит, что если вы ищете для процесса Баша тока, используйте либо $$ (для родительского PID текущей оболочки) или $BASH_PID (для самых текущей оболочки , даже если это подоболочка), а не использовать так неточный инструмент как pgrep или pidof.

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