왜`grep -v`가 예상대로 작동하지 않습니까?


12

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쿼리가 오작동 하는지 전혀 모른다 .


4
사용하는 방법에 대한 어떻게 set -x그런 다음 명령을 실행하고 당신이 실제로하려고하는 것을 볼 수 ... 첫번째 grep...
— don_crissti

@don_crissti 아, 알겠습니다; 실제로 grep"tty가 아님"을 말하는 것 입니다. 내가이 문제를 어떻게 해결하겠습니까?
— 아마 maybeharry

답변:


18

Zachary는 문제의 원인을 설명했습니다.

당신이 그것을 해결할 수있는 동안

tty=$(tty)
tty_without_dev=${tty#/dev/}
who | grep -v "$tty_without_dev"

예를 들어 tty가 pts/1이면 포함하는 모든 행을 제외하게됩니다 pts/10. 일부 grep구현에는 -w단어 검색을 수행하는 옵션이 있습니다

who | grep -vw pts/1

에 단어가 아닌 문자가 pts/10없기 때문에에 일치 pts/1하지 않습니다.

또는 다음 awk과 같이 두 번째 필드의 정확한 값을 필터링 하는 데 사용할 수 있습니다 .

who | awk -v "tty=$tty_without_dev" '$2 != tty'

하나의 명령으로 수행하려면 다음을 수행하십시오.

{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0

원래 stdin은 파일 설명자 3에 복제되어 tty명령을 위해 복원됩니다 .


3
한 번의 명령으로 수행하는 방법을 알아 내고 그 실수를 지적한 +1
— Zachary Brady

라이너 하나 더 :tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
— axxis

20

tty 정보 페이지에서.

'tty'는 표준 입력에 연결된 터미널의 파일 이름을 인쇄합니다. 표준 입력이 터미널이 아닌 경우 'not tty'를 인쇄합니다.

문제는 예제에서 tty의 stdin이 터미널이 아닌 파이프라는 것입니다.

이 예제에서 볼 수 있습니다.

$ tty
/dev/pts/29
$ echo | tty 
not a tty

그 문제를 해결하려면 다음과 같이 할 수 있습니다.

who | grep -wv "$(ps ax | awk "\$1 == $$ {print \$2}" )"

더 빠르고 효율적인 방법이 있지만 두 가지 명령이 필요합니다.

t=$(tty)
who|grep -wv "${t:5}"

@Christopher 당신은 당신의 컴퓨터에 로그인 한 유일한 사람입니까?
— Zachary Brady

@ 크리스토퍼, 이상하다. 따라서 who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"내 상자에서 예상되는 출력을 t=$(tty) who|grep -v "${t:5}"생성하고 아무것도 생성하지 않습니다.
— Zachary Brady

어떤 쉘 / 버전을 사용하고 있습니까? GNU bash, version 4.1.2
— Zachary Brady

2
ps ax | grep "^ *$$"셸이 123이고 1234가 존재하는 경우, 일치하지 않을 수 있습니다. ps ax -otty= $$더 강력하고 단 하나의 프로세스입니다. 그러나 나는 당신 ${t:5}이나 Stephane 's ${t#/dev/}(또는 substr(t,6))를 선호합니다
— dave_thompson_085

1
면책 조항을 추가하지 마십시오. 의도는 칭찬 할 만하지 만 실제로 답변을 돕는 것은 아닙니다. 누군가가 귀하의 답변에 결함을 지적하면 수정 사항을 포함하도록 답변을 편집하십시오.
— terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.