У меня странная проблема, связанная с grep -v
запросами. Позвольте мне объяснить:
Для отображения подключений я использую who
:
$ who
harry pts/0 2016-12-08 20:41 (192.168.0.1)
james pts/1 2016-12-08 19:28 (192.168.0.1)
timothy pts/2 2016-12-08 02:44 (192.168.0.1)
Ток tty
моего терминалаpts/0
$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0
Я пытаюсь исключить мою собственную связь, используя grep -v $(tty | cut -f3-4 -d'/')
. Ожидаемый вывод этой команды должен быть who
без моего подключения. Однако вывод наиболее неожиданный:
$ who | grep -v $(tty | cut -f3-4 -d'/')
grep: a: No such file or directory
grep: tty: No such file or directory
Я заключил $(...)
в кавычки, и это, кажется, решить проблему "Нет такого файла или каталога". Тем не менее, мое соединение все еще печатается, хотя мой tty ( pts/0
) должен был быть исключен:
$ who | grep -v "$(tty | cut -f3-4 -d'/')"
harry pts/0 2016-12-08 20:41 (192.168.0.1)
james pts/1 2016-12-08 19:28 (192.168.0.1)
timothy pts/2 2016-12-08 02:44 (192.168.0.1)
На данный момент я абсолютно не знаю, почему grep
запрос работает неправильно.
command-line
grep
tty
perhapsmaybeharry
источник
источник
set -x
сначала ... Затем запустите свою команду и посмотрите, что вы на самом деле пытаетесьgrep
...grep
"не TTY". Как бы вы посоветовали мне обойти это?Ответы:
Захари объяснил источник проблемы.
Хотя вы можете обойти это с
Это было бы неправильно, как, например, если это tty
pts/1
, вы бы в конечном итоге исключили все строки, содержащиеpts/10
. В некоторыхgrep
реализациях есть-w
возможность поиска по словуне будет соответствовать,
pts/10
потому что заpts/1
ним не следует символ, не состоящий из слов.Или вы можете использовать
awk
для фильтрации на точное значение второго поля, как:Если вы хотите сделать это одной командой:
Исходный stdin дублируется на файловый дескриптор 3 и восстанавливается для
tty
команды.источник
tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
Со страницы tty info.
Проблема в том, что в вашем примере tty's stdin - это канал, а не ваш терминал.
Вы можете видеть из этого примера.
Чтобы обойти это, вы можете сделать что-то вроде этого.
Существует более быстрый / более эффективный способ, однако он требует двух команд.
источник
who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"
выдает ожидаемый результат на моей коробке иt=$(tty) who|grep -v "${t:5}"
ничего не производит.GNU bash, version 4.1.2
ps ax | grep "^ *$$"
может совпадать, например, ваша оболочка 123 и 1234 существует;ps ax -otty= $$
является более надежным и только один процесс. Но я предпочитаю вашу${t:5}
или Стефана${t#/dev/}
(илиsubstr(t,6)
)