여러 명령을 다른 기호로 연결하는 온라인 자습서가 종종 있습니다. 예를 들면 다음과 같습니다.
command1 | command2
command1 & command2
command1 || command2
command1 && command2
다른 사람들은 명령을 파일에 연결하는 것 같습니다.
command1 > file1
command1 >> file1
이것들은 무엇입니까? 그들은 무엇을 불렀습니까? 그들은 무엇을합니까? 더 있나요?
답변
이것을 쉘 연산자라고하며 더 많은 것이 있습니다. 두 가지 주요 클래스 인 제어 연산자 와 리디렉션 연산자 중 가장 일반적인 클래스 와 bash 셸과 관련하여 작동하는 방법에 대해 간략하게 설명합니다 .
A. 제어 연산자
쉘 명령 언어에서 제어 기능을 수행하는 토큰.
다음 기호 중 하나입니다.& && ( ) ; ;; <newline> | ||
그리고 |&
bash에서.
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을 리턴하십시오. 또한test
유틸리티에 대한 논리적 NOT입니다 .! 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
파일이 존재하지 않으면 생성됩니다.
이 연산자는 명령이 일반적으로 stdin 에서만 읽기 때문에 거의 사용되지 않지만 여러 가지 특정 상황에서 유용 할 수 있습니다 .
-
>
: 명령 출력을 파일로 보냅니다.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
그 안에 이미 무엇이든 후, 여기에 추가됩니다. 존재하지 않는 경우 작성됩니다. -
&>
,>&
,>>&
과&>>
(비표준). 표준 오류와 표준 출력을 각각 대체하거나 추가하여 리디렉션하십시오.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
인용, 여기에 문서의 텍스트는 문자 그대로 처리하고 더 확장 (예 : 변수) 수행되지 않습니다. 인용 부호가 없으면 변수가 확장됩니다. 자세한 내용은 bash 매뉴얼을 참조하십시오 .출력
command << WORD ... WORD
을 다른 명령 또는 명령 으로 직접 파이프하려면 파이프를와 같은 행에<< WORD
배치해야합니다. 종료 단어 다음에 또는 다음 행에 파이프를 배치 할 수 없습니다. 예를 들면 다음과 같습니다.command << WORD | command2 | command3... Text WORD
-
<<<
: 여기 문서와 유사하지만 한 줄로 된 문자열입니다. 이것들은 유닉스 포트 또는 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에도 construct <(…)
가 >(…)
있으며 =(…)
(후자 zsh
만). 이는 리디렉션이 아니라 프로세스 대체 입니다.
답변
‘>’에 관한 경고
단지 I / O 리디렉션 (에 대해 배운 유닉스 초보자 <
와는 >
) 종종 같은 것들을 시도
명령 ... input_file > the_same_file
또는
명령 ... < 파일 > the_same_file
또는 거의 동등하게
고양이 파일 | 명령 ...> the_same_file
( grep
, sed
, cut
, sort
, 그리고 spell
사람들이 이런 구조에 사용하는 유혹 명령의 예입니다.) 사용자는 이러한 시나리오가 비어되는 파일이 발생할 것을 발견 놀랄 수 있습니다.
다른 답변에서 언급되지 않은 뉘앙스 는 bash (1) 의 Redirection 섹션의 첫 번째 문장에 숨어 있습니다 .
명령이 실행되기 전에
셸이 해석하는 특수 표기법을 사용하여 입력 및 출력을 리디렉션 할 수 있습니다 .
처음 5 개 단어는 굵게, 기울임 꼴, 밑줄, 확대, 깜박임, 빨간색으로 표시되고 아이콘으로 표시되어 명령을 실행하기 전에 셸이 요청 된 리디렉션을 수행한다는 사실을 강조
해야합니다 . 또한 기억하십시오
출력을 재 지정하면 파일을 쓰기 위해 열린다.… 파일이 존재하지 않으면 파일이 작성됩니다. 존재하는 경우 크기가 0으로 잘립니다.
-
따라서이 예에서
sort roster > roster
셸
roster
은sort
프로그램 실행을 시작 하기 전에 파일을 잘라서 잘라서 잘라냅니다 (즉, 내용을 모두 버림) . 당연히, 데이터를 복구하기 위해 아무것도 할 수 없습니다. -
순진하게 기대할 수도 있습니다.
tr "[:upper:]" "[:lower:]" < poem > poem
더 좋을 수도 있습니다. 쉘은 왼쪽에서 오른쪽으로 경로 재 지정을 처리 하므로, 쓰기를 위해 열기 전에 (표준 출력을 위해)
poem
읽기 위해 (tr
표준 입력을 위해) 열립니다. 그러나 도움이되지 않습니다. 이 일련의 조작으로 두 개의 파일 핸들이 생성되지만 둘 다 동일한 파일을 가리 킵니다. 셸에서 읽을 파일을 열면 내용이 그대로 있지만 프로그램이 실행되기 전에 여전히 내용이 잘립니다.
그래서 어떻게해야합니까?
솔루션은 다음과 같습니다.
-
실행중인 프로그램에 출력 위치를 지정하는 고유 한 내부 기능이 있는지 확인하십시오. 이것은 종종
-o
(또는--output=
) 토큰으로 표시됩니다 . 특히,sort roster -o roster
대략적으로
sort roster > roster
첫 번째 경우를 제외하고
sort
프로그램은 출력 파일을 엽니 다. 때까지 그리고 출력 파일을 열 수없는만큼 똑똑 후에 는 입력 파일 (들)을 모두 읽을 수있다.이와 유사하게, 적어도 일부 버전
sed
이-i
(편집 내가 다시 입력 파일로 출력 출력을 작성하는 데 사용할 수있는 N 장소) 옵션을 (다시, 이후 모든 입력이 읽은). 같은 편집자ed
/ex
,emacs
,pico
, 및vi
/은vim
사용자가 텍스트 파일을 편집하고 원본 파일에서 편집 된 텍스트를 저장할 수 있습니다. 있습니다ed
(적어도)는 비 대화식으로 사용할 수 있습니다.vi
관련 기능이 있습니다. 을 입력 하면에 편집 버퍼의 내용을 출력하고 출력을 읽고이를 버퍼에 삽입합니다 (원본 내용을 바꿉니다).:%!command
Entercommand
-
간단하지만 효과적인:
명령 … input_file > temp_file && mv temp_file input_file
이는
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의 2 배가됩니다. (당신은 같은 옵션을 사용해야 할 수도-a
나-p
에 대한cp
특성을 보존하도록 지시 할 수 있습니다.)command … input_file > temp_file &&
cp --attributes-only --preserve=all input_file temp_file &&
mv temp_file input_file
(가독성을 위해 별도의 행으로 분리됨) 파일의 모드 (루트 인 경우 소유자)를 유지하지만 사용자가 소유 한 파일 (루트하지 않은 경우)을 만들고 새 파일로 만듭니다. 별도의 파일.
-
이 블로그
( “파일 내”편집)는 제안하고 설명합니다.{rm input_file && command …> input_file ; } < input_file
이를 위해서는
command
표준 입력을 처리 할 수 있어야하지만 거의 모든 필터가 가능합니다. 블로그 자체는 이것을 위험한 kludge라고하며 사용을 권장하지 않습니다. 그리고 이것은 또한 당신이 소유하고 기본 권한을 가진 새로운 별도의 파일 (아무것도 링크되지 않은)을 만듭니다. -
moreutils 패키지에는 다음과 같은 명령이 있습니다
sponge
.명령 … input_file | 스폰지 the_same_file
자세한 내용은 이 답변 을 참조하십시오.
나에게 완전히 놀랐던 것이있다 :
syntaxerror 말한다 :
[이러한 솔루션의 대부분은] “읽기 전용”당신이 있다는 것을 의미 읽기 전용 파일 시스템에 실패
$HOME
할 것이다 쓸 수 있지만/tmp
됩니다 읽기 전용 (기본적으로). 예를 들어, Ubuntu가 있고 복구 콘솔로 부팅 한 경우가 일반적입니다. 또한, 여기-문서 운영자<<<
가 필요로 하나가 작동하지 않습니다/tmp
수 읽기 / 쓰기
그것뿐만 아니라 거기에 임시 파일을 쓰기 때문입니다.
(cf. 이 질문 에는strace
‘d 출력 이 포함됩니다 )
이 경우 다음이 작동 할 수 있습니다.
- 고급 사용자의 경우 :
명령이 입력이 같은 출력 데이터의 같은 양을 생산하기 위해 보장되어있는 경우 (예를 들어,sort
또는tr
없이-d
또는-s
옵션), 당신은 시도 할 수 있습니다명령 … input_file | dd of = the_same_file conv = notrunc
참조 이 답변
하고 이 응답 명령이 입력이 같은 출력 데이터의 같은 양을 생산하기 위해 보장되어있는 경우 작동 위의 설명을 포함한 자세한 내용은, 대안 이하 (예를 들어,grep
또는cut
). 이 답변은 여유 공간이 필요하지 않거나 매우 적은 이점이 있습니다. 위의 형식에 대한 답은 시스템이 전체 입력 (이전) 파일과 출력 (새) 파일을 동시에 보유 할 수있는 충분한 여유 공간이 필요하다는 것을 분명히 요구합니다. 이는 대부분의 다른 솔루션 (예 : 및 )에도 해당되지 않습니다. 예외 : 여유 공간이 많이 필요할 것입니다 .
command … input_file > temp_file && …
sed -i
sponge
sort … | dd …
sort
출력을 쓰기 전에 모든 입력을 읽어야하며, 모든 파일이 임시 파일에있는 것은 아니지만 대부분 버퍼링합니다. - 고급 사용자 만 해당 :
명령 … input_file 1 <> the_same_file
dd
위의 답변 과 동일 할 수 있습니다 . 이 구문은 파일 디스크립터에서 이름 지정된 파일을 잘라 내지 않고 입력 및 출력 모두에 대해 –
및 의 조합으로 엽니 다 . 참고 : 일부 프로그램 (예 : 및 )은 입력과 출력이 동일한 파일임을 감지 할 수 있으므로이 시나리오에서 실행을 거부 할 수 있습니다.
위의 설명에 대해서는 이 대답 을 참조 하고 명령이 input이 있거나 같은 양의 출력 데이터를 생성하도록 보장 된 경우이 답변을 작동시키는 스크립트를 참조하십시오 .
경고 : Peter의 스크립트를 테스트하지 않았으므로 보증하지 않습니다.n<> file
n
n<
n>
cat
grep
그래서 질문은 무엇입니까?
이것은 U & L에서 인기있는 주제였습니다. 다음 질문에서 다룹니다.
- 내부에서 파일을 수정하는 방법이 있습니까?
iconv
입력 파일을 변환 된 출력으로 바꾸 려면 어떻게 해야합니까?- 명령
shuf file > file
이 빈 파일을 남기는 이유는 무엇 입니까? - 덮어 쓰지 않고 Linux에서 동일한 파일을 읽고 쓸 수 있습니까?
- 명령으로 처리 된 소스 파일과 동일한 파일로 리디렉션
- 이
sort
명령 이 왜 빈 파일을 제공합니까? tr
stdout을 파일로 리디렉션- grep : 입력 파일 ‘X’도 출력
- 리디렉션 연산자가 파일 디스크립터를 병렬로 열습니까?
- 파일을 덮어 쓰지 않고 빈 파일 만 생성하는 리디렉션
… 그리고 그것은 슈퍼 유저 나 Ask Ubuntu를 포함하지 않습니다. 위의 질문에 대한 답변의 많은 정보를이 답변에 통합했지만 전부는 아닙니다. (자세한 내용은 위에 나열된 질문과 답변을 읽으십시오.)
추신 : 나는 위에 인용 한 블로그와 아무런 관련 이 없습니다 .
답변
더 관찰에 ;
, &
, (
및)
-
terdon의 답변에있는 일부 명령은 null 일 수 있습니다. 예를 들어
command1 ;
(없음
command2
). 이것은command1
(즉, 단순히
command1
포 그라운드에서 실행 되고 완료 될 때까지 기다립니다.command1 &
(no
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