Выход трубопровода для обрезки

Я пытаюсь получить имя оболочки, выполняющей script.

Почему

echo $(ps | grep $PPID) | cut -d" " -f4

работает

echo ps | grep $PPID | cut -d" " -f4

не?

Ответ 1

Причина в том, что

echo ps

просто печатает строку ps; он не запускает программу ps. Исправлена ​​версия вашей команды:

ps | grep $PPID | cut -d" " -f4

Отредактировано для добавления: paxdiablo указывает, что ps | grep $PPID содержит много пробелов, которые будут свернуты на echo $(ps | grep $PPID) (так как результат $(...), когда он не в двойных кавычках, разделяется пробелом на отдельные аргументы, а затем echo выводит все свои аргументы, разделенные пробелами). Чтобы решить эту проблему, вы можете использовать tr для "сжимания" повторяющихся пробелов:

ps | grep $PPID | tr -s ' ' | cut -d' ' -f5

или вы можете просто придерживаться того, что вам нужно было начать.: -)

Ответ 2

Первая строка:

echo $(ps | grep $PPID) | cut -d" " -f4

говорит:

  • Выполнить ps | grep $PPID в под-оболочке
  • Вернуть результат - что-то вроде этого:

    3559 pts/1 00:00:00 bash
    

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

  • Затем запустите cut -d" " -f4, который дает вам имя команды в этом случае

Вторая команда:

echo ps | grep $PPID | cut -d" " -f4

говорит:

  • Эхо-строка ps
  • Grep эта строка для $PPID - это никогда не вернет ничего, поскольку $PPID содержит число, поэтому оно никогда не будет ps. Таким образом, grep ничего не возвращает
  • Выполнить cut -d" " -f4 с вводом предыдущей команды - ничего, поэтому ничего не получится

Ответ 3

Я думаю, что если вы запускаете только echo ps самостоятельно, вы увидите, почему ваш канал не работает:

$ echo ps
ps

Вместо этого отметьте $0. Обратите внимание, что это может быть -bash или bash, в зависимости от того, является ли это оболочкой входа. (Ну, любая оболочка - не просто bash - но дефис добавляется, если оболочка является оболочкой входа.)