"-"로 시작하는 파일 이름을 잘못 해석하지 않도록 인용을 사용하지 않는 이유는 무엇입니까? [복사]

"-"로 시작하는 파일 이름을 잘못 해석하지 않도록 인용을 사용하지 않는 이유는 무엇입니까? [복사]

이것은 터무니없는 게시물일 수 있지만 이라는 파일이 있다고 가정할 때 -|h4k3r|-이 참조가 작동하지 않는 이유는 무엇입니까?

cat '-|h4k3r|-'

작은따옴표가 모든 특수 문자의 의미를 제거한다고 생각했습니까?

그러나 이것은 작동합니다

cat -- -\|h4k3r\|- 

이것은 또한:

cat "./-|h4k3r|-"

그런데 왜 이것이 작동하지 않는지 이해가 안 되나요?

cat "-|h4k3r|-"

이 예에서 참조가 예상대로 작동하지 않는 이유를 이해하려고 노력하고 있습니다.

'-어쩌면 Bash는 "-또는??에 대해 특별한 의미를 가질 수도 있습니다.

답변1

그 이유는 작은따옴표가 실제로 특수 문자의 의미를 제거하지만 이는 다음을 참조하기 때문입니다.변수 확장, 와일드카드 및 단어 분할- 그 특수 문자껍질을 벗기다쉘로 해석됨결과가 프로그램에 전달되기 전에- 및 셸 메타 문자(예 |: ).

이런 의미에서는 -"특수 문자"가 아닙니다. 특별한 점은 바로사실은프로그램이 시작하는 문자열을 프로그램에 표시하는 표준 방법은 "옵션" 인수입니다. 실제로 Unix/Linux 생태계의 대부분은 아니지만 많은 프로그램이 외부 리소스에 의존합니다.getopt()이 목적으로 사용되는 함수 1은 명령줄 인수를 처리하는 표준화된 방법을 제공하는 POSIX 사양의 일부이며 -"옵션"으로 시작하는 인수를 해석하는 규칙이 여기에 포함되어 있습니다.

따라서 작은따옴표는 -|h4ker|-쉘에서 프로그램으로 축어적으로 전달되도록 보장합니다( cat귀하의 경우).그러나 그 과정에서 따옴표도 제거되었습니다.. 따라서 프로그램은 여전히 ​​이 매개변수가 a로 시작하므로 -피연산자(처리할 파일 이름과 같은)가 아닌 "옵션" 매개변수로 처리되어야 한다고 생각합니다.

이것이 바로 많은 프로그램(역시 이에 의존하는 모든 프로그램 getopt()) --이 명령줄의 토큰을 특수 "옵션 끝" 표시로 해석하여 로 시작하는 파일에 안전하게 적용될 수 있는 이유입니다 -.

조사에서 이미 탐색한 또 다른 가능성은 파일 이름을 절대 파일 이름( '/path/to/file/-|h4ker|-')으로 선언하거나 현재 디렉터리( './-|h4ker|-')를 추가하여 파일 이름을 "보호"하는 것입니다. 그러면 매개 변수가 더 이상 "모호한" 시작으로 끝나지 않습니다 -.이 예에서는 여전히 인용/이스케이프가 필요합니다.|쉘 메타 문자이기 때문입니다 .

좋은 데모는 다음과 같은 파일을 생성하고 나열하는 것입니다 -l.

~$ touch '-l'
touch: Invalid option -- l
~$ touch -- '-l'
~$ ls '-l'

< ... the entire directory content in long list format ... >

~$ ls -- '-l'
-l
~$ ls -l -- '-l'
-rw-r--r-- 1 user user 0 Feb 24 17:16 -l

1 셸 스크립트의 경우 이에 상응하는 스크립트가 있습니다.getopts내장 명령

답변2

가지다프로그램은 여기서 작동합니다.
하나는 셸이고 다른 하나는 cat프로그램/실행 파일/유틸리티입니다.

쉘은 "인용" 옵션으로 작은따옴표를 유지하지만, cat은 그렇지 않습니다.

쉘은 -(인수에서) 초기 대시( )에 특별한 의미를 부여하지 않지만 cat은 그렇습니다.

쉘은 몇 가지 규칙에 따라 실행 프로그램의 매개변수를 변경합니다.

$ echo '-|h4k3r|-'
-|h4k3r|-

$ echo "-|h4k3r|-"
-|h4k3r|-

$ echo -\|h4k3r\|-
-|h4k3r|-

echo명령은 동일한 인수 -|h4k3r|-(따옴표 제거 후)를 수신하고 위의 세 가지 경우 모두 동일한 결과를 인쇄합니다. 님의 참조가 |삭제되었습니다.특별한껍질에 의미가 있습니다.

echo명령에는 옵션이 거의 없으며 초기 대시( -)를 완전히 이해하지 못하므로 추가 작업이 필요하지 않습니다.

하지만 페이지에 명시된 cat대로 많은 옵션이 있습니다 . man cat옵션은 일반적 -으로 및로 시작합니다.모두다음 문자는 -명령으로 처리되어야 합니다 cat(일부 운영 체제에서는 해당되지 않음). 예를 들어, cat -n file파일의 각 줄에는 번호가 매겨져 있습니다.

$ cat file
Line 1
Line 2

$ cat -n file
    1 Line 1
    2 Line 2

그러나 options으로 끝나고 --여전히 a 를 추가 하면 -n파일 이름으로 해석됩니다 cat.

$ cat -- -n file
cat: -n: No such file or directory
Line 1
Line 2

파일명(실제로는 경로)을 , ./또는 ../( /이 디렉터리, 상위 디렉터리, 루트 디렉터리)로 시작하여 직접 쓸 수 있기 때문입니다.

관련 정보