이것은 터무니없는 게시물일 수 있지만 이라는 파일이 있다고 가정할 때 -|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
파일명(실제로는 경로)을 , ./
또는 ../
( /
이 디렉터리, 상위 디렉터리, 루트 디렉터리)로 시작하여 직접 쓸 수 있기 때문입니다.