Страница 1 из 1
передача параметра в утилиту конвейером
Добавлено: 2009-07-09 12:13:39
initYs
Всем привет. Есть вопрос такого плана, боюсь, что он относится к базовым, но я пока так и не смог нарыть ответа.
Есть некая утилита (допустим ps) в нее надо передать параметр через конвейер.
Есть ли стандартный метод передачи переменных через конвейер в софт который не имеет встроенной поддержки (может какая то системная переменная)?
Чтобы было понятнее что я хочу - поясню:
вот, есть например такая команда. Но необходимо убрать perl, а передавать параметр напрямую в ps.
Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+/[0-9]+" -printf %f\\n | perl -ne 'chomp; `ps -p $_ h -o pid` || print "the pid $_ is missing!\n"'
Если использовать формы вида
Код: Выделить всё
ps h -o pid -p $( find /proc -maxdepth 1 -type d -regex "/.+/[0-9]+" -printf %f\\n )
Код: Выделить всё
ps h -o pid -p <<< echo $( find /tmp -maxdepth 1 -type d -regex "/.+/[0-9]+" -printf %f\\n )
то невозможно определить статус операции для каждого передаваемого параметра. Вобщем, это только иллюстрация вопроса - сам вопрос озвучен выше.

Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-09 18:00:15
terminus
xargs
Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+/[0-9]+" -printf %f\\n | xargs ps
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-09 21:51:37
initYs
Спасибо, то что надо, но все равно проблема не решилась. )) Точнее вылезла другая, после find передается не каждый идентификатор процесса в ps, а списком "pid1 pid2...pidN", поэтому xargs (точнее ps) всегда возвращает 0 статус, даже если несколько процессов из списка он не может найти. Чего не происходит, если передавать поочередно, это по идеи можно было бы осуществить через -exec или -execdir, но они к сожалению не понимают сложных выражений. Так что придётся, видимо оставить как есть с использованием perlа, правда надо его еще чуток подкрутить.

Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-09 22:36:06
terminus
В качестве гуманитарной помощи:
Код: Выделить всё
#!/bin/sh
for STR in `find /proc -maxdepth 1 -type d -regex "/.+/[0-9]+" -printf %f\\n`
do
ps $STR
if [ $? -ne 0 ]
then
echo "ps $STR vernul oshibku - ne znaju kak teper' dalshe zhit' voobshe :("
else
echo "vse ok"
fi
done
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 2:41:16
Гость
у автора темы какой-то чересчур сложный пример (ну не знаю я /proc, gnu find, perl). Может он не в курсе, что find умеет простейший flow control?
Код: Выделить всё
$ find /proc \
-maxdepth 1 \
-type d \
-regex "/.+/[0-9]+" \
\( \
-execdir ps -p {} -o pid \; \
-or \
-execdir echo "the pid {} is missing!" \; \
\)
и что -exec (и -execdir) следуют ведут себя адекватно, если программа выходит со статусом > 0.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 2:47:27
Гость
да и xargs тоже управляем,
Код: Выделить всё
$ find... | xargs -I% sh -c 'ps -p % -o pid || echo "the pid % is missing!"'
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 8:20:59
initYs
ага, спсибо за уточнения и за помощь. Я действительно не был в курсе, только разбираюсь в bash-скриптинге. Сейчас буду пробовать
upd. просто я тренируюсь в разных аспектах bash-скриптинга и пытаюсь разобраться в нюансах. Поэтому пытаюсь уложить задачу в однострочную команду.
Гость писал(а):у автора темы какой-то чересчур сложный пример (ну не знаю я /proc, gnu find, perl). Может он не в курсе, что find умеет простейший flow control?
Код: Выделить всё
$ find /proc \
-maxdepth 1 \
-type d \
-regex "/.+/[0-9]+" \
\( \
-execdir ps -p {} -o pid \; \
-or \
-execdir echo "the pid {} is missing!" \; \
\)
и что -exec (и -execdir) следуют ведут себя адекватно, если программа выходит со статусом > 0.
вся проблема в том, что возвращается при поиске на pid а ./pid, поэтому напрямую подставить нельзя {} в команду. Но в любом случае, есть на чем подумать дополнительно уже.
C xargs получилось все как хотел

Еще раз спасибо, за пищу для размышлений.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 8:56:51
initYs
И вопрос в догонку чтобы не плодить тем )) можно ли определить текущий pid для команды?
Что то вроде
Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -printf "your pid is %f\\n" &
[1] 2872
$ your pid is 31679
$ echo $PPID
31679
то есть видно, что в таком виде возвращается pid текущей оболочки, а не самого процесса find.
Или пример еще проще - как увидеть pid команды echo, а не шела?
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 11:31:05
Гость
initYs писал(а):upd. просто я тренируюсь в разных аспектах bash-скриптинга и пытаюсь разобраться в нюансах. Поэтому пытаюсь уложить задачу в однострочную команду.
если хочешь помощи, то старайся придерживаться поведения POSIX shell'а. На bash'е скрипты тут мало кто пишет. Если уж писать, то на zsh или python'е.
initYs писал(а):вся проблема в том, что возвращается при поиске на pid а ./pid, поэтому напрямую подставить нельзя {} в команду. Но в любом случае, есть на чем подумать дополнительно уже.
а ты ставил -execdir, а не -exec? на фряшном find'е {} - имя файла без пути и `./'
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 11:39:26
initYs
ну да пробовал, на RHEL
Код: Выделить всё
find --version
GNU find версии 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX
вывод поиска
Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
./14619
я неплохо знаю perl, на нем много чего и пишу/писал. Но хочется немного научиться адвансед программированию на шеле. Но без фанатизма, конечно. С питоном может позже попробую разобраться.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 11:53:15
Гость
btw, нафиг ты проходишь /proc с помощью find'а. Если будешь парсить вывод ps, то overhead будет меньше за счет меньше числа syscall'ов.
initYs писал(а):то есть видно, что в таком виде возвращается pid текущей оболочки, а не самого процесса find.
нет, PPID (parent pid) возвращает PID родителя оболочки, в коей запущен find. Сама оболочка - $$.
Вообще-то ты не можешь отдать процессу в argv его собственный PID предварительно не зарезервировав shell'ом этот самый PID. А так процесс может получить свой PID по getpid(2).
initYs писал(а):Или пример еще проще - как увидеть pid команды echo, а не шела?
echo - встроенная команда в sh- и csh-подобных shell'ах. Конечно она имеет такой же PID, как и у shell'а.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 11:57:46
Гость
initYs писал(а):Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
./14619
Код: Выделить всё
$ find -E /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
1694
Ы

Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:04:52
Гость
initYs писал(а):Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
./14619
кстати, ты можешь убрать `./' впереди без вызова внешних программ (кроме shell'а) так
Код: Выделить всё
$ find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir sh -c 'f={}; echo ${f##*/}' \;
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:05:39
initYs
btw, нафиг ты проходишь /proc с помощью find'а. Если будешь парсить вывод ps, то overhead будет меньше за счет меньше числа syscall'ов.
тут весь прикол, чтобы получить перечень процессов из /proc и сравнить с теми что показывает ps. Если есть скрытые для ps процессы - показать.
Да с echo, я тормознул, конечно. Про передачу параметров - все верно, точно не смогу. Спасибо за разъяснения.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:07:12
initYs
Гость писал(а):initYs писал(а):Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
./14619
Код: Выделить всё
$ find -E /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
1694
Ы

Код: Выделить всё
find -E /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir echo '{}' \;
find: неверный предикат `-E'
что за опция?
Гость писал(а):кстати, ты можешь убрать `./' впереди без вызова внешних программ (кроме shell'а) так
Код: Выделить всё
$ find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir sh -c 'f={}; echo ${f##*/}' \;
Код: Выделить всё
find /proc -maxdepth 1 -type d -regex "/.+$PPID" -execdir sh -c 'f={}; echo ${f##*/}' \;
sh: ./f=14619: Нет такого файла или каталога
хмм интересная конструкция, просто в шелле работает. Тут видимо затык в передача параметра через {}. попробую разобраться.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:21:27
Гость
initYs писал(а):что за опция?
заставляет -regex понимать расширенные регулярные выражения.
http://en.wikipedia.org/wiki/Regular_ex ... xpressionsinitYs писал(а):тут весь прикол, чтобы получить перечень процессов из /proc и сравнить с теми что показывает ps. Если есть скрытые для ps процессы - показать.
а что в linux нет опции для ps, чтобы показывать скрытые процессы?
initYs писал(а):Про передачу параметров - все верно, точно не смогу.
хм, почему нет. Кто мешает сделать exec() и завладеть PID'ом родителя?
Код: Выделить всё
$ sh -c 'ps -lp $$'
UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND
1001 58682 1699 0 44 0 7012 1468 - R+ 5 0:00.00 ps -lp 58682
где sh -c 'ps -lp $$' == sh -c 'exec ps -lp $$'
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:43:13
initYs
я чего спрашивал - у себя найти не смог, ни в help, ни в man. Возможно версии разные утилит.
Гость писал(а):а что в linux нет опции для ps, чтобы показывать скрытые процессы?'
ну дело ж не в этом, а в практике юзанья шелл-скриптинга.. Вот уже на получал столько инфы, что не успеваю переваривать )))
Гость писал(а):
хм, почему нет. Кто мешает сделать exec() и завладеть PID'ом родителя?
Код: Выделить всё
$ sh -c 'ps -lp $$'
UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND
1001 58682 1699 0 44 0 7012 1468 - R+ 5 0:00.00 ps -lp 58682
где sh -c 'ps -lp $$' == sh -c 'exec ps -lp $$'
Ага, идея понятна. Спасибо, есть над чем подумать и о чем почитать более подробно.
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:54:58
Гость
initYs писал(а):я чего спрашивал - у себя найти не смог, ни в help, ни в man. Возможно версии разные утилит.
http://man.freebsd.org/find/1
http://netbsd.gw.com/cgi-bin/man-cgi?find+1
правда в OpenBSD ее почему-то нет. ;\
initYs писал(а):Ага, идея понятна. Спасибо, есть над чем подумать и о чем почитать более подробно.
короче вот ответ на изначальный вопрос
Код: Выделить всё
$ bash -c 'find /proc -maxdepth 1 -type d -regex "/.+$$" -printf "your pid is %f\\n"'
your pid is 71531
где 71531 - PID find'а
Re: передача параметра в утилиту конвейером
Добавлено: 2009-07-10 12:58:50
initYs
Гость писал(а):initYs писал(а):я чего спрашивал - у себя найти не смог, ни в help, ни в man. Возможно версии разные утилит.
http://man.freebsd.org/find/1
http://netbsd.gw.com/cgi-bin/man-cgi?find+1
правда в OpenBSD ее почему-то нет. ;\
initYs писал(а):Ага, идея понятна. Спасибо, есть над чем подумать и о чем почитать более подробно.
короче вот ответ на изначальный вопрос
Код: Выделить всё
$ bash -c 'find /proc -maxdepth 1 -type d -regex "/.+$$" -printf "your pid is %f\\n"'
your pid is 71531
где 71531 - PID find'а
я уже понял, мерси!
