Почему эта команда sed не может захватить шаблон?

Вы проверяете его параметры.

[ "$-" = "${-#*i}" ] ||
echo shell is interactive

Вы также можете проверить его файловые дескрипторы. Это немного другое. Он не обязательно скажет вам, является ли оболочка интерактивной как таковой, но он сообщит вам, общается ли она с терминалом.

for fd in 0 1 2
do     [ -t "$fd" ] && 
       break 
done|| echo shell fds 0 1 2 are not connected to a terminal.

Мы можем немного взломать это, чтобы попытаться обнаружить все используемые процессы нашего терминала.

tty_users()
    for fd in 0 1 2 "$@"
    do     [ -t "$fd" ] && {
           fuser "$(tty)"
           break; } <&"$fd"
    done 

Которая будет запущена в текущей оболочке и распечатает список идентификаторов процессов для тех процессов, которые запущены на первом обнаруженном терминале, как связанные с std (in | out | err) (по умолчанию - передать функцию числовые аргументы для проверки других) соответственно. Он устанавливает для оболочки var $ fd номер дескриптора файла, связанный с этим терминалом, и возвращает false, если ни один из стандартных дескрипторов или каких-либо аргументов не связан с терминалом.

Вышеупомянутое, вероятно, так близко, как вы получите, если вы не поищете идентификатор сеанса вашего терминала - если он у вас есть.

ps -osid= -p"$$"

Это вернет вам pid владельца вашего управляющего терминала - если он у вас есть.

Чтобы продемонстрировать:

echo "$$"; sh -c 'sh -c "ps -osid= -p\"\$$\""' 

6023
6023

Но вы не можете полагаться ни на что из этого. Вовсе нет. Смотрите:

sh -acm 'IFS=\; i=0;eval "$0"'          \
        '[ "$i" -lt 5 ] && eval "$*"'   \
        'ps -opid -opgid -p"$$"'        \
        'sh -acm "$0" "$0" "$@" i=$((i+=1))'
  PID  PGID
28766 28766
  PID  PGID
28768 28768
  PID  PGID
28770 28770
  PID  PGID
28772 28772
  PID  PGID
28774 28774

Видите? Интерактивной оболочки, из которой я запускаю эти процессы, нет даже в этом списке. Каждый sh запускает собственный дочерний элемент, пока не будет достигнута глубина 5, и при каждом запуске вызывает ps для печати своего PID и PGID. Каждый процесс получает новый PGID. Управление заданиями так же связано с интерактивной оболочкой, как и терминал, просто терминал - это более прямой способ проверить это.

2
14.06.2018, 03:54
2 ответа

\1будет ссылаться на первую группу захвата. Поскольку в настоящее время у вас нет группы захвата, вы можете определить совпадение как группу захвата, окружив его фигурными скобками и сославшись на него, используя\1:

$ echo 1 | sed 's/\(.*\)/(\1)/'
(1)
1
27.01.2020, 21:53

&— это стандартный способ замены всего совпадения с образцом.Некоторые реализации sed, такие как GNU или busybox, поддерживают \0в качестве альтернативы, но это не стандартно и не переносимо.

$ echo 1 | sed -e 's/.*/(&)/'
(1)

Эта команда заключает в скобки первую (возможно пустую )последовательность из символов , как можно больше в каждой строке. Это может не включать полную строку для тех строк, которые содержат байты, не образующие допустимые символы, и в этом случае вы можете обнаружить, что:

sed 's/^/(/; s/$/)/'

Работает более надежно, заключая полную строку в круглые скобки.

6
27.01.2020, 21:53

Теги

Похожие вопросы