$ echo > 1 2 3; ls -latr 1; cat 1
-rw-rw-r-- 1 kahn kahn 4 Jun 23 14:05 1
2 3
이것이 리디렉션 평가와 관련이 있습니까 >
? 그래서:
echo > 1 2 3
기술적으로 다음과 같이 다시 작성할 수도 있습니다.
echo 2 3 > 1
?
IO 리디렉션의 작업 순서와 평가 방법을 더 잘 이해하는 데 도움이 될 수 있는 리소스가 있습니까? 이 예가 유용하지 않거나 일반적이지 않을 수도 있다는 점은 인정하지만 여기서 정확히 무슨 일이 일어나고 있는지 더 잘 이해하고 싶습니다.
답변1
참고할 수 있는 적절한 리소스는 POSIX입니다.쉘 구문, 간단한 명령을 다음과 같이 정의합니다.
simple_command : cmd_prefix cmd_word cmd_suffix | cmd_prefix cmd_word | cmd_prefix | cmd_name cmd_suffix | cmd_name ;
여기서 가장 관련성이 높은 부분은 다음의 정의입니다 command_suffix
.
cmd_suffix : io_redirect | cmd_suffix io_redirect | WORD | cmd_suffix WORD ;
이는 재귀적이므로 리디렉션 및 명령 매개변수가 어떤 순서로든 나타날 수 있습니다.
또한 POSIX는 다음을 정의합니다.리디렉션 구문~처럼
[n]redir-op word
n
선택적 숫자와 리디렉션 연산자( >
귀하의 경우) 사이에는 공백이 허용되지 않지만 리디렉션 연산자와 다음 단어 사이에는 공백이 허용됩니다. 확장되면 word
( 1
귀하의 경우)은 스트림이 전달되는(또는 원본에서) 파일의 이름으로 사용됩니다.
그러므로 글을 쓰는 것도 합법이다.
$ echo > 1 foo bar
# ^^^^ ^^^^^^^^^^^^^
# \ \
# \ cmd_suffix
# \ ^^^ ^^^ ^^^
# \ \ \ \
# \ \ \ WORD
# \ \ WORD
# \ io_redirect
# cmd_name
또는
$ echo foo >1 bar
심지어
$ echo > 1 foo > 1 bar > 1
(물론 반복은 > 1
아무 의미가 없습니다.)
완전성을 기하기 위해 cmd_prefix
the 정의 simple_command
자체는 재귀적으로 정의됩니다.
cmd_prefix : io_redirect | cmd_prefix io_redirect | ASSIGNMENT_WORD | cmd_prefix ASSIGNMENT_WORD ;
이는 리디렉션과 변수 할당이 어떤 순서로든 명령 앞에 나타날 수 있음을 의미합니다.
예를 들어 다음과 같이 할 수 있습니다.
$ LC_ALL=C <infile sort >outfile 2>errfile
# ^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^
# \ \ \
# cmd_prefix cmd_word cmd_suffix
또는
$ 2>errfile >outfile <infile LC_ALL=C sort
또는
$ LC_ALL=C sort <infile 2>errfile >outfile
이것들은 모두 동일하게 유효하지만 리디렉션, 변수 할당 및 확장은 왼쪽에서 오른쪽으로 수행되며 순서가 관련될 수 있다는 점을 기억해야 합니다(예: infile
존재하지 않으면 outfile
잘리지 않습니다 cat <infile >outfile
) cat >outfile <infile
.
답변2
단어는 공백으로 구분됩니다. 따옴표 붙은 문자열은 공백에 관계없이 단일 단어로 처리됩니다. 변수의 값은 사용될 때 토큰화의 후보입니다(이것이 일반적으로 변수 이름을 큰따옴표로 묶는 것이 가장 좋은 이유입니다 "$var"
).
리디렉션 연산자는 다음 단일 단어를 사용합니다.
자세한 내용은 쉘의 매뉴얼 페이지(예: man bash
"확장" 아래) 에서 확인할 수 있습니다.
확장 순서는 중괄호 확장, 물결표 확장, 매개변수, 변수 및 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행), 토큰화 및 경로 이름 확장입니다.