echo > 1 2 3 은 왜 내용이 2 3 인 1이라는 파일을 생성합니까?

echo > 1 2 3 은 왜 내용이 2 3 인 1이라는 파일을 생성합니까?
$ 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_prefixthe 정의 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"확장" 아래) 에서 확인할 수 있습니다.

확장 순서는 중괄호 확장, 물결표 확장, 매개변수, 변수 및 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행), 토큰화 및 경로 이름 확장입니다.

관련 정보