2015-08-02 2 views
4

Вот тест:Разница между pgrep в ш и Баш

$ bash -c "pgrep -f novalidname" 
$ sh -c "pgrep -f novalidname" 
11202 

Почему pgrep дает выход при запуске из sh? (Насколько я могу видеть, нет процессов на моем компьютере, который называется novalidname)

ответ

5

Это, вероятно, вопрос времени и pgrep находит себя, как вы будете его выдачи с -f и novalidname присутствует в командной строке , Попробуйте установить -l.

+0

Да, кажется, так .. Например, это дает также выход: 'Баш -c«сон 1; pgrep -f novalidname»' –

+0

Это не вопрос времени. Это оптимизация bash, аналогичная оптимизации Tail Call Optimization. – rici

+0

Я подозреваю, что в системе OP '/ bin/sh' просто ссылка на'/bin/bash'. И что? – mustaccio

1

Это одна вещь (оказавшаяся из-за задержки) смотри также:

$ ps ax | grep novalidname 

Здесь обычно показывает, как хорошо. (На Ubuntu делает для меня. (Под Баш)

Другая вещь, что/бен/ш связан с?

На большинстве Linux дистрибутивов/бен/ш представляет собой мягкую ссылку по умолчанию оболочку, которая, как правило, на самом деле bash, но может быть любой другой оболочкой.

Разница во времени, которая вызывает отображение grep/pgrep, может быть введена путем поиска местоположения мягкой ссылки (hm, odd) или некоторой другой оболочки, связанной с/bin/sh который выполняется немного иначе, чем bash, что вызывает задержку, необходимую для процесса для отображения в pgrep.

Кроме того, bash сначала попытается использовать источник ~/.bash rc и загрузить его историю, в то время как/bin/sh будет делать то, что будет делать. В .bashrc может быть pgrep определен как псевдоним другим способом, который также может повлиять на разницу.

Чтобы увидеть, где/бен/ш точки, чтобы сделать:

$ readlink -e /bin/sh 

Или просто запустить ш, чтобы посмотреть, что будет отображаться. : D

2

Действительное объяснение:

  1. Независимо от флагов, pgrepникогда возвращает свой собственный PID.

  2. Если выполнить bash -c с помощью простой команды, то баш будет exec команду, а не создавать избыточную подоболочку выполнить его. Следовательно, bash -c "pgrep -f blah" будет заменить на bash процесс с pgrep процесса. Если этот процесс pgrep является единственным процессом, в командной строке которого blah, то pgrep не отображает никаких PID (согласно 1).

  3. dash не выполняет вышеуказанную оптимизацию. (zsh и ksh делать.) Так что, если в вашей системе, sh осуществляются с dash, то sh -c "pgrep -f blah" приведет два процесса выполняется - в sh процесс и pgrep ребенка - оба из которых содержат blah в своих командных строках. pgrep не сообщит о себе, но он сообщит о своем родителе.

+0

_ «pgrep никогда не возвращает свой собственный PID» _ - как вы можете быть уверены, даже не зная, с какой ОС мы имеем дело? – mustaccio

+0

@mustaccio: он задокументирован в man-странице pgrep. Независимо от ОС, для процесса легко получить свой собственный PID, поэтому для pgrep тривиально исключить его из списка. Тот факт, что pgrep делает эту гарантию, является одной из причин, по которой это гораздо лучший инструмент, чем grepping вывода ps. – rici

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