file $(ls /usr/bin/* | grep zip) 명령을 실행하면 오류가 발생합니다. 뭐가 문제 야?

file $(ls /usr/bin/* | grep zip) 명령을 실행하면 오류가 발생합니다. 뭐가 문제 야?

나는 Linux/Unix에 관한 책을 읽기로 결정했습니다. 나는 명령의 출력을 확장으로 쉘에 파이프하는 방법을 설명하는 장을 읽었습니다.

다음 명령

file $(ls /usr/bin/* | grep zip)

대신에 "'파일 이름(해당 파일이나 디렉터리 없음)을 열 수 없습니다."라는 오류가 표시됩니다.

file $(ls | grep zip)

폴더에 관계없이 모든 것이 정상적으로 표시됩니다. 왜? 이것은 일종의 논쟁 제한입니까?

만약 내가한다면

file $(ls Pictures/ | grep jpg)

다음 메시지가 나타납니다.

1234.jpg: ERROR: cannot open 1234.jpg (No such file or directory)

나열하려는 디렉토리로 바로 이동할 때

nassosdim@ubuntu:~$ cd Pictures/

nassosdim@ubuntu:~/Pictures$ file $(ls | grep jpg)

파일의 결과를 인쇄

1234.jpg: JPEG image data, JFIF standard 1.01

누군가 나에게 무슨 일이 일어나고 있는지 설명해 줄 수 있습니까? :(

답변1

이 오류는 bash가 *glob 패턴 일치를 사용하여 인수를 ls로 확장하려고 시도하기 때문에 발생합니다. glob이 패턴과 일치하지 않으면 항상 이와 같은 오류가 발생합니다. 그런 다음 실제 별표로 *전달되는데 ls, 이는 파일과도 일치하지 않으므로 ls오류가 발생합니다!

현재 수행 중인 작업에 대해 중복되는 몇 가지 사항이 있습니다. 귀하가 구조를 배우려고 노력하고 있다는 것을 알고 있지만 방금 달성한 내용과 이를 달성한 방법을 분석해 보겠습니다.

  1. ls /usr/binbin 디렉토리에 있는 파일을 나열하는 것으로 충분하며 별표는 전혀 필요하지 않습니다.
  2. 넌 절대 안 돼출력 구문 분석ls그럼에도 불구하고 이는 모호하고 잠재적으로 위험합니다.
  3. 다음을 수행하여 grep 없이 동일한 효과를 얻을 수 있지만 ls /usr/bin/*zip*이는 ls여전히 중복되므로 glob 확장을 파일에 전달할 수 있습니다.file /usr/bin/*zip*

마지막으로, find파일을 찾는 데 더 좋은 도구가 있는 경우가 많습니다. 다음과 같이 원하는 것을 할 수 있습니다.

$ find /usr/bin -iname '*zip*' -exec file {} +

답변2

*쉘은 명령을 확장 하고 로 변환합니다 file $(ls /usr/bin/a /usr/bin/b /usr/bin/whatever | grep zip). 쉘이 별표를 로 전달하도록 하려는 경우가 아니면 UNIX에서는 별표를 지정할 필요가 없습니다 ls.

즉, 쉘은 *를 일치하는 각 파일로 대체합니다.앞으로명령을 실행하는데, 이는 익숙하다면 Windows에서 작동하는 방식이 아닙니다.

여기에서 섹션 3.4.9를 읽어보세요..

file $(ls /usr/bin/ | grep zip) 

*가 필요하지 않지만 다른 질문과 옵션에 대해서는 Caleb의 답변을 참조한다는 의미에서 올바른 접근 방식입니다. 하지만 실제로 실행되는 것은

file /usr/bin/a /usr/bin/b /usr/bin/whatever

아니요

file /usr/bin/a
file /usr/bin/b
file /usr/bin/whatever

다시 말하지만 Windows와는 다르게 이 작업을 수행합니다.

답변3

ls /usr/bin/* | grep zip당신이 제공하는 인수를 확인해 보세요 file. 결과가 조금 혼란스럽네요. 내 Ubuntu 시스템에서 결과는 다음과 같습니다.

/usr/bin/funzip
/usr/bin/gpg-zip
/usr/bin/mzip
/usr/bin/preunzip
/usr/bin/prezip
/usr/bin/prezip-bin
/usr/bin/unzip
/usr/bin/unzipsfx
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
funzip
gpg-zip
mzip
preunzip
prezip
prezip-bin
unzip
unzipsfx
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit

이를 사용하면 ls /usr/bin/* | less이 결과가 나오는 이유를 알 수 있습니다. /usr/bin에 있는 모든 파일 다음에 ls/usr/bin/X11 디렉토리의 내용도 나열되며 디렉토리 이름 앞에 추가하지 않고 나열됩니다.

디렉터리 이름 없이 이러한 파일 이름을 지정하면 file파일 file을 찾을 수 없으며 "해당 파일이나 디렉터리가 없습니다"라는 오류 메시지가 표시됩니다. (참고: 오류 메시지가 표시되면 "오류가 발생했습니다"라고만 말하지 마세요. "하지만 오류 메시지를 게시합니다).

Caleb이 이미 게시한 것처럼 file /usr/bin/*zip*.

답변4

ls출력 형식이 다양하기 때문에 결과를 구문 분석하는 것은 위험한 작업이 될 수 있습니다. 다음과 같이 하는 것이 더 나을 것입니다.

file /path/to/*.zip

프로세스 교체가 어떻게 작동하는지 보여주기 위해 더 간단한 명령을 사용해 보십시오.

ls $(echo /usr/bin) 

관련 정보