다양한 기호를 사용하여 다양한 명령을 연결하는 온라인 튜토리얼을 자주 봅니다. 예를 들어:
command1 | command2
command1 & command2
command1 || command2
command1 && command2
다른 사람들은 명령을 파일에 연결하는 것 같습니다.
command1 > file1
command1 >> file1
이것들은 무엇입니까? 이름은 무엇입니까? 그들은 무엇을 하고 있나요? 더 있나요?
답변1
이를 쉘 연산자라고 하며, 그 외에도 더 있습니다. 두 가지 주요 범주 중 가장 일반적인 범주를 간략하게 설명하겠습니다.제어 연산자그리고리디렉션 연산자, 그리고 bash 쉘에서 작동하는 방식.
A. 제어 연산자
쉘 명령 언어에서 제어 기능을 실행하는 태그.
다음 기호 중 하나입니다.
& && ( ) ; ;; <newline> | ||
배쉬 에서 |&
.
A !
는아니요제어 연산자이지만예약어. 논리 NOT [부정 연산자]가 됩니다.산술 표현내부 테스트 구조(여전히 공백 구분 기호가 필요함).
A.1 목록 종결자
;
: 첫 번째 명령의 결과에 관계없이 다른 명령이 완료된 후 하나의 명령을 실행합니다.command1 ; command2
먼저 command1
전경에서 실행되고 완료되면 command2
실행됩니다.
문자열 리터럴에 없거나 특정 키워드 뒤에 줄 바꿈이 없습니다.아니요세미콜론 연산자와 동일합니다. 간단한 명령의 구분된 목록 ;
은 여전히 있습니다.목록- 쉘의 파서와 마찬가지로 ;
별도의 단순 명령을 따르는 단순 명령은 실행 전에 읽어야 하며 줄 바꿈은 전체 명령 목록 또는 목록 목록을 구분할 수 있습니다. 차이점은 미묘하지만 복잡합니다. 개행은 쉘이 개행 이후의 데이터를 읽는 이전 명령이 없다고 가정하고 쉘이 읽은 간단한 명령을 평가하기 시작할 수 있는 지점을 표시하는 반면 세미콜론은 ;
그렇지 않습니다.
&
: 백그라운드에서 명령이 실행되므로 동일한 셸에서 계속 작업할 수 있습니다.command1 & command2
여기서는 command1
백그라운드에서 시작하고 종료를 command2
기다리지 않고 즉시 포그라운드에서 실행을 시작합니다 command1
.
다음 개행 문자는 command1
선택 사항입니다.
A.2 논리 연산자
&&
: 다른 명령이 성공적으로 종료된 경우에만 하나의 명령을 실행할 수 있는 AND 목록을 작성하는 데 사용됩니다.command1 && command2
완료되면 여기에서 실행 command2
됩니다 .command1
오직성공한 경우 command1
(종료 코드가 0인 경우) 두 명령 모두 포그라운드에서 실행됩니다.
이 명령은 다음과 같이 쓸 수도 있습니다.
if command1
then command2
else false
fi
아니면 if command1; then command2; fi
반품 상태를 무시하세요.
||
: 다른 명령이 종료되지 않는 경우에만 하나의 명령을 실행할 수 있는 OR 목록을 작성하는 데 사용됩니다.command1 || command2
여기서는 command2
실패 시에만 실행됩니다 command1
(0이 아닌 종료 상태가 반환되는 경우). 두 명령 모두 포그라운드에서 실행됩니다.
이 명령은 다음과 같이 쓸 수도 있습니다.
if command1
then true
else command2
fi
아니면 더 짧은 방법으로요 if ! command1; then command2; fi
.
&&
과 는 ||
연관되어 있음을 참고 하세요.쉘 논리 연산자 && 및 ||의 우선순위더 많은 정보를 알고 싶습니다.
!
: 이것은 "not" 연산자 역할을 하는 예약어입니다(단, 구분 기호가 있어야 함). 명령의 반환 상태를 부정하는 데 사용됩니다. 명령이 0이 아닌 상태를 반환하면 0을 반환합니다. 상태 0이면 1을 반환합니다. 프로그램 논리 NOT 1을 반환하는 것도 실용적입니다test
.! command1 [ ! a = a ]
산술 표현식의 실제 NOT 연산자:
$ echo $((!0)) $((!23))
1 0
A.3 파이프라인 운영자
|
: 한 명령의 출력을 다른 명령의 입력으로 전달하는 파이프 연산자입니다. 파이프 연산자에서 작성된 명령이 호출됩니다.관로.command1 | command2
인쇄된 모든 출력은
command1
에 입력으로 전달됩니다command2
.|&
2>&1 |
: 이것은 bash와 zsh의 약어입니다. 한 명령의 표준 출력과 표준 오류를 다른 명령의 입력으로 전달합니다.command1 |& command2
A.4 기타 목록 구두점
;;
끝을 표시하는 데에만 사용됩니다.사례 진술. Ksh, bash 및 zsh는 ;&
다음 사례로 점프하고 ;;&
(ATT ksh에서는 아님) 후속 사례를 계속 테스트하는 기능도 지원합니다.
(
그리고 )
익숙해지세요그룹 명령서브쉘에서 시작합니다. {
및 }
그룹 명령을 사용하지만 서브셸에서 실행하지는 마세요. 바라보다이 답변쉘 구문의 다양한 유형의 괄호, 대괄호 및 중괄호에 대해 토론하십시오.
B. 리디렉션 연산자
쉘 명령 언어에서 리디렉션 기능을 수행하는 토큰입니다. 다음 기호 중 하나입니다.
< > >| << >> <& >& <<- <>
이를 통해 명령의 입력과 출력을 제어할 수 있습니다. 간단한 명령 내에서나 명령 뒤에 나타날 수 있습니다. 리디렉션은 표시된 순서대로 왼쪽에서 오른쪽으로 처리됩니다.
<
: 명령을 입력합니다.command < file.txt
위 내용은 command
의 내용에 따라 실행됩니다 file.txt
.
<>
: 위와 동일하지만 파일이 다음 위치에서 열립니다.읽기+쓰기대신 패턴읽기 전용:command <> file.txt
파일이 존재하지 않으면 생성됩니다.
이 연산자는 거의 사용되지 않습니다. 왜냐하면 명령은 일반적으로읽다그러나 표준 입력에서다양한 특정 상황에서 유용할 수 있습니다..
>
: 명령의 출력을 파일로 보냅니다.command > out.txt
위의 내용은 출력을 command
. out.txt
파일이 있으면 해당 내용을 덮어쓰고, 파일이 없으면 파일이 생성됩니다.
이 연산자는 또한 무엇인가를 인쇄할지 여부를 선택하는 데 자주 사용됩니다.표준 에러또는표준 출력:
command >out.txt 2>error.txt
위의 예에서는 >
표준 출력이 리디렉션되고 2>
표준 오류가 리디렉션됩니다. 리디렉션된 출력을 사용하는 것도 가능 1>
하지만 이것이 기본값이므로 1
일반적으로 생략하고 간단히 >
.
따라서 이를 실행 command
하고 오류 메시지와 함께 file.txt
출력을 저장하려면 다음을 실행합니다.out.txt
error.txt
command < file.txt > out.txt 2> error.txt
>|
: : 와 동일>
하지만 쉘이 덮어쓰기를 거부하도록 구성되어 있어도(set -C
또는 사용set -o noclobber
) 대상을 덮어씁니다.command >| out.txt
있는 경우 out.txt
의 출력이 command
해당 내용을 대체합니다. 존재하지 않는 경우 생성됩니다.
>>
: 과 동일>
하지만 대상 파일이 존재하는 경우 새 데이터가 추가됩니다.command >> out.txt
out.txt
존재하는 경우 command
이미 존재하는 항목에 출력을 추가합니다. 존재하지 않는 경우 생성됩니다.
>&
: (POSIX 사양에 따라) 다음으로 둘러싸인 경우숫자(1>&2
) 또는-
오른쪽 (1>&-
) 리디렉션만 가능하나파일 설명자를 삭제하거나 닫습니다(>&-
).
>&
파일 설명자 번호 뒤에 오는 것은 파일 설명자를 리디렉션하는 이식 가능한 방법이자 파일 >&-
설명자를 닫는 이식 가능한 방법입니다.
이 리디렉션의 오른쪽이 파일인 경우 다음 항목을 읽으세요.
>&
,&>
및 :( 위>>&
참조&>>
) 표준 오류 및 표준 출력을 각각 바꾸거나 추가하여 리디렉션합니다.command &> out.txt
표준 오류와 표준 출력은 모두 command
에 저장되며 out.txt
내용을 덮어쓰거나 내용이 없으면 새로 생성됩니다.
command &>> out.txt
위와 동일합니다. 단 out.txt
, 존재하는 경우 의 출력과 오류가 command
추가됩니다.
이 &>
변종은 bash
csh >&
(수십년 전)에서 유래되었습니다. 이들은 모두 다른 POSIX 셸 연산자와 충돌하므로 이식 가능한 스크립트에 사용하면 안 됩니다 sh
.
<<
: 여기에 문서가 있습니다. 일반적으로 여러 줄 문자열을 인쇄하는 데 사용됩니다.command << WORD Text WORD
여기에서는 위의 예에서 다음 항목이 발견될 때까지 모든 것이 입력으로 사용
command
됩니다 . 일반적 으로 또는 그 변형이지만 원하는 영숫자(단지) 문자열이 될 수 있습니다 . 의 일부가 인용되거나 이스케이프되면 여기 문서의 텍스트는 문자 그대로 처리되며 확장(예: 변수)이 수행되지 않습니다. 따옴표 없이 두면 변수가 확장됩니다. 자세한 내용은 다음을 참조하세요.WORD
Text
WORD
EoF
WORD
배쉬 매뉴얼.command << WORD ... WORD
출력을 다른 명령으로 직접 파이프 하려면 파이프를<< WORD
종료하는 WORD 뒤나 뒤의 줄이 아닌 와 동일한 줄에 배치해야 합니다. 예를 들어:command << WORD | command2 | command3... Text WORD
<<<
: 여기의 문자열은 여기의 document와 유사하지만 한 줄입니다. 이는 Unix 포트 또는 rc(원래 위치), zsh, ksh, yash 및 bash의 특정 구현에만 존재합니다.command <<< WORD
주어진 모든 것은 WORD
확장되고 해당 값은 에 입력으로 전달됩니다 command
. 이는 일반적으로 변수의 내용을 명령에 입력으로 전달하는 데 사용됩니다. 예를 들어:
$ foo="bar"
$ sed 's/a/A/' <<< "$foo"
bAr
# as a short-cut for the standard:
$ printf '%s\n' "$foo" | sed 's/a/A/'
bAr
# or
sed 's/a/A/' << EOF
$foo
EOF
다른 연산자( >&-
, x>&y
x<&y
)를 사용하여 파일 설명자를 닫거나 복사할 수 있습니다. 이에 대한 자세한 내용은 쉘 매뉴얼의 관련 섹션(여기예: 배시).
여기서는 Bourne과 유사한 쉘에 대한 가장 일반적인 연산자만 다룹니다. 일부 셸에는 자체적인 추가 리디렉션 연산자가 있습니다.
Ksh, bash 및 zsh에도 <(…)
, >(…)
및 구조가 있습니다 =(…)
(후자만 zsh
). 이는 리디렉션이 아닙니다.프로세스 교체.
답변2
">"에 대한 경고
I/O 리디렉션 ( <
및>
주문하다…입력 파일>같은 파일
또는
주문하다…<문서 >같은 파일
또는 거의 동등하게,
고양이문서|주문하다… >같은 파일
( grep
, sed
, cut
및 sort
는 spell
사람들이 이러한 구조에서 사용하려고 하는 명령의 예입니다.) 사용자는 이러한 상황으로 인해 파일이 비어 있을 수 있다는 사실에 놀랐습니다.
다른 답변에서는 언급되지 않는 미묘한 차이점은 첫 번째 문장에서 찾을 수 있습니다리디렉션부분큰 타격(1):
명령이 실행되기 전에 명령의 입력과 출력이 변경될 수 있습니다.리디렉션 쉘에서 해석되는 특수 기호를 사용하십시오.
처음 5개 단어는 굵게, 기울임꼴, 밑줄, 확대, 깜박임, 빨간색이어야 하며 아이콘으로 표시하여 셸이 요청 리디렉션을 수행한다는 사실을 강조해야 합니다. 명령 실행 전. 또한 기억하세요
출력 리디렉션으로 인해 파일이 쓰기 위해 열립니다.... 파일이 없으면 생성되고, 있으면 0 크기로 잘립니다.
따라서 이 예에서는 다음과 같습니다.
sort roster > roster
쉘은 쓰기를 위해 파일을 열고
roster
프로그램 실행이 시작되기 전에 파일을 잘라냅니다(즉, 모든 내용을 삭제합니다).sort
물론 데이터를 복구하기 위해 아무 것도 할 수 없습니다.순진하게 기대할 수도 있다
tr "[:upper:]" "[:lower:]" < poem > poem
더 좋을 수도 있습니다. 쉘은 왼쪽에서 오른쪽 방향 재지정을 처리하기 때문에 쓰기(표준 출력)를 위해 열기 전에
poem
읽기(tr
표준 입력)를 위해 열립니다. 그러나 이것은 도움이 되지 않습니다. 이 일련의 작업에서는 두 개의 파일 핸들이 생성되지만 둘 다 동일한 파일을 가리킵니다. 셸이 읽기 위해 파일을 열 때 내용은 그대로 남아 있지만 프로그램이 실행되기 전에 여전히 손상되었습니다.
그러면 어떻게 해야 합니까?
솔루션에는 다음이 포함됩니다.
실행 중인 프로그램에 출력 위치를 지정하는 자체 내부 기능이 있는지 확인하세요. 이는 일반적
-o
으로 (또는) 표시로 표시 됩니다--output=
. 특히,sort -o roster roster
대략 동등하다
sort roster > roster
첫 번째 경우를 제외하고
sort
프로그램은 출력 파일을 엽니다. 그 전까지는 충분히 똑똑해뒤쪽에모든 입력 파일을 읽었습니다.마찬가지로, 적어도 일부 버전
sed
에는-i
(편집나n 위치) 옵션은 출력을 입력 파일에 다시 쓰는 데 사용할 수 있습니다(마찬가지로,뒤쪽에모든 입력을 읽었습니다.)ed
/ex
,emacs
, /pico
등vi
의 편집기를 사용하면vim
사용자가 텍스트 파일을 편집하고 편집된 텍스트를 원본 파일에 저장할 수 있습니다.ed
(적어도) 비대화형 으로 사용할 수 있습니다.vi
관련 기능이 있습니다. 입력하면 편집 버퍼의 내용을 씁니다.:%!command
Entercommand
, 출력을 읽고 이를 버퍼에 삽입합니다(원본 콘텐츠 대체).
간단하지만 효과적인:
주문하다…입력 파일>임시 파일 && MV임시 파일 입력 파일
이는 다음과 같은 단점이 있습니다.
input_file
링크이므로 (아마도) 별도의 파일로 대체됩니다. 또한 새 파일은 귀하의 소유가 되며 기본적으로 보호됩니다. 특히 이로 인해 원본 파일이 있더라도 파일을 전 세계에서 읽을 수 있게 되는 위험이 발생합니다.input_file
아니요.다양성:
command … input_file > temp_file && cp temp_file input_file && rm temp_file
이건 아직도 (아마도) 떠난다temp_file
세상은 읽을 수 있습니다. 더 좋은 점은 다음과 같습니다.cp input_file temp_file && command … temp_file > input_file && rm temp_file
이는 파일의 링크 상태, 소유자 및 모드(보호)를 유지하지만 I/O 비용이 두 배로 늘어날 수 있습니다. ( 속성을 보존하려면-a
또는-p
on 과 같은 옵션을 사용해야 할 수도 있습니다 .)cp
command … input_file > temp_file &&
cp --attributes-only --preserve=all input_file temp_file &&
mv temp_file input_file
(가독성을 위해 별도의 줄로 구분) 이는 파일의 모드(루트인 경우 파일의 소유자)를 유지하지만 해당 파일을 사용자의 것으로 만들고(루트가 아닌 경우) 새로운 별도의 파일로 만듭니다.
이 블로그 (파일의 "내부" 편집) 제안 및 설명
{RM입력 파일 && 주문하다… >입력 파일; } <입력 파일
이를 위해서는
command
표준 입력을 처리할 수 있습니다(그러나 거의 모든 필터가 처리합니다). 블로그 자체에서는 이를 위험한 패치워크라고 부르며 사용을 권장하지 않습니다. 그러면 귀하가 소유하고 기본 권한을 갖는 별도의 새 파일(아무것에도 연결되지 않음)이 생성됩니다.moreutils 패키지에는 다음 명령이 있습니다
sponge
.주문하다…입력 파일|스펀지같은 파일
바라보다이 답변더 많은 정보를 알고 싶습니다.
나를 완전히 놀라게 한 것은 다음과 같습니다. 문법 오류가 말합니다:
[이러한 솔루션의 대부분은] 읽기 전용 파일 시스템에서는 실패합니다. 여기서 "읽기 전용"은
$HOME
~ 할 것이다쓸 수 있지만/tmp
그럴 것이다읽기 전용(기본적으로). 예를 들어 Ubuntu가 있고 복구 콘솔로 부팅한 경우 이는 일반적입니다. 또한 이 문서 연산자는 필요<<<
에 따라 작동하지 않습니다 ./tmp
읽기/쓰기 임시 파일도 쓰기 때문입니다.
(보다이 문제strace
'd 출력 포함 )
이 경우 다음이 작동할 수 있습니다.
- 고급 사용자에게만 해당:
명령이 입력과 동일한 양의 출력 데이터를 생성하도록 보장되는 경우(예:
sort
또는tr
아니요-d
또는 옵션-s
) 시도해 볼 수 있습니다.주문하다…입력 파일dd =같은 파일변환=notrunc
바라보다이 답변 그리고이 답변위의 설명과 명령이 입력과 동일한 양의 출력 데이터를 생성하도록 보장하는 가능한 대안을 포함하여 자세히 알아보세요.이하(예:grep
, 또는cut
). 이러한 답변의 장점은 여유 공간이 필요하지 않다는 것입니다(또는 공간이 거의 필요하지 않음). 위 표에 대한 대답은 시스템에 전체 입력(기존) 파일과 출력(새) 파일을 모두 수용할 수 있는 충분한 여유 공간이 있어야 함을 명시적으로 요구합니다. 이는 대부분의 다른 솔루션(예: 및 ) . 예외: 출력을 쓰기 전에 모든 입력을 읽어야 하고 임시 파일의 대부분(전부는 아니지만)의 데이터를 버퍼링할 수 있으므로 많은 여유 공간이 필요할 수 있습니다.command … input_file > temp_file && …
sed -i
sponge
sort … | dd …
sort
- 고급 사용자에게만 해당:
주문하다…입력 파일1<>같은 파일
dd
아마도 위의 답변 과 동일할 것입니다 . 이 구문은 파일 설명자에서 지정된 파일을 엽니다.n<> file
n
입력과 출력을 위해 , 자르지 않고 - 일종의 and 의 조합과 같습니다. 참고: 일부 프로그램(예: 및 )은 입력과 출력이 동일한 파일임을 감지할 수 있기 때문에 이 경우 실행을 거부할 수 있습니다. 바라보다n<
n>
cat
grep
이 답변 위의 내용에 대한 논의와 명령이 입력과 동일한 양의 출력 데이터를 생성하도록 보장되는 경우 이 답변이 작동하도록 하는 스크립트이하.
경고: Peter의 스크립트를 테스트하지 않았으므로 보장할 수 없습니다.
그렇다면 문제는 무엇입니까?
이는 U&L의 인기 주제이며 다음 질문으로 해결됩니다.
- 파일을 제자리에서 수정하는 방법이 있나요?
iconv
입력 파일을 변환된 출력으로 바꾸는 방법은 무엇입니까 ?- 이 명령이
shuf file > file
빈 파일을 남기는 이유는 무엇입니까? - 덮어쓰지 않고 Linux에서 동일한 파일을 읽고 쓸 수 있습니까?
- 명령어로 처리된 소스 파일과 동일한 파일로 리다이렉트
- 이
sort
명령이 빈 파일을 제공하는 이유는 무엇입니까? tr
표준 출력을 파일로 리디렉션- grep: 입력 파일 "X"도 출력됩니다.
- 리디렉션 연산자가 파일 설명자를 병렬로 열 수 있나요?
- 리디렉션은 파일을 덮어쓰지 않고 빈 파일만 생성합니다.
...수퍼 유저나 Ask Ubuntu는 포함되지 않습니다. 위 질문에 대한 답변의 많은 정보를 이 답변에 포함했지만 전부는 아닙니다. (즉, 자세한 내용은 위에 나열된 질문과 답변을 읽어보세요.)
추신 : 나는아니요위에 언급한 블로그와 연결됩니다.
답변3
;
&
, (
및 에 대한 추가 관찰)
terdon의 답변에 있는 일부 명령은 비어 있을 수 있습니다. 예를 들어 다음과 같이 말할 수 있습니다.
command1 ;
(아니요
command2
). 이는 다음과 같습니다.command1
(즉,
command1
전경에서 실행되고 완료될 때까지 기다립니다. 대조적으로,command1 &
(없음)은
command2
백그라운드에서 시작된 다음 즉시 다른 쉘 프롬프트를 발행합니다.command1
반면,
command1 &&
,command1 ||
, 는command1 |
의미가 없습니다. 이들 중 하나를 입력하면 쉘은 명령이 다른 행으로 계속되는 것으로 가정합니다. 일반적으로 로 설정된 보조(계속) 쉘 프롬프트가 표시되고>
계속해서 읽습니다. 쉘 스크립트에서는 다음 줄을 읽고 읽은 내용에 추가합니다. (참고: 이는 귀하가 원하는 일이 아닐 수도 있습니다.)참고: 일부 쉘의 일부 버전에서는 이러한 불완전한 명령을 오류로 처리할 수 있습니다. 이 경우(또는 실제로어느
\
명령이 매우 긴 경우) 줄 끝에 백슬래시( )를 추가하여 쉘이 다른 줄에서 명령을 계속 읽도록 지시할 수 있습니다.command1 && \ command2
또는
find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \ -newer some_existing_file -user fred -readable -print
terdon이 말했듯이
(
명령)
을 그룹화하는 데 사용할 수 있습니다. 이 논의와 "관련성이 적다"는 주장은 논쟁의 여지가 있습니다. terdon의 답변에 나오는 명령 중 일부는 명령일 수 있습니다.그룹. 예를 들어,( command1 ; command2 ) && ( command3; command4 )
이 작업을 수행:
- 실행
command1
하고 완료될 때까지 기다립니다. - 그런 다음 첫 번째 명령 실행 결과가 무엇이든 실행
command2
하고 완료될 때까지 기다립니다. 그래서
command2
성공하면,- 실행
command3
하고 완료될 때까지 기다립니다. - 그런 다음 결과에 관계없이 명령을 실행
command4
하고 완료될 때까지 기다립니다.
실패 하면
command2
명령줄 처리를 중지합니다.- 실행
- 실행
괄호 밖에서는
|
조합이 매우 빡빡해서command1 | command2 || command3
동등하다
( command1 | command2 ) || command3
그리고
&&
보다||
더 밀접하게 묶여;
있으므로command1 && command2 ; command3
동등하다
( command1 && command2 ) ; command3
즉,
command3
및/또는 종료 상태에 관계없이 실행됩니다.command1
command2