수색…
통사론
- 명령 </ path / to / file # 표준 입력을 파일로 재 지정
- command> / path / to / file # 표준 출력을 flie로 재 지정
- 명령 file_descriptor> / path / to / file # file_descriptor의 출력을 파일로 리디렉션
- command> & file_descriptor # 출력을 file_descriptor로 리디렉션합니다.
- 명령 file_descriptor> & another_file_descriptor # file_descriptor를 another_file_descriptor로 리디렉션합니다.
- command <& file_descriptor # file_descriptor를 표준 입력으로 리디렉션
- &> / path / to / file # 표준 출력 및 표준 오류를 파일로 리디렉션
매개 변수
매개 변수 | 세부 |
---|---|
내부 파일 기술자 | 정수. |
방향 | > , < 또는 <> 중 하나 |
외부 파일 기술자 또는 경로 | & 파일 기술자 또는 경로 정수 하였다. |
비고
UNIX 콘솔 프로그램에는 입력 파일과 두 개의 출력 파일 (장치뿐만 아니라 입력 및 출력 스트림도 파일로 취급됩니다.)은 일반적으로 키보드와 스크린이지만, 그 중 일부 또는 전부를 리디렉션 할 수 있습니다 파일이나 다른 프로그램에서 오거나 갈 수 있습니다.
STDIN
은 표준 입력이며 프로그램이 대화식 입력을 수신하는 방법입니다. STDIN
은 대개 파일 설명자 0이 할당됩니다.
STDOUT
은 표준 출력입니다. STDOUT
방출되는 것은 프로그램의 "결과"로 간주됩니다. STDOUT
은 대개 파일 설명자 1이 할당됩니다.
STDERR
은 오류 메시지가 표시되는 곳입니다. 일반적으로 콘솔에서 프로그램을 실행하면 STDERR
이 화면에 출력되고 STDOUT
과 구별 할 수 없습니다. STDERR
은 대개 파일 설명자 2가 할당됩니다.
리디렉션 순서가 중요합니다.
command > file 2>&1
STDOUT
및 STDERR
모두 파일로 리디렉션합니다.
command 2>&1 > file
파일 설명자 2가 파일 설명자 1이 가리키는 파일로 리디렉션되기 때문에 STDOUT
만 리디렉션합니다 (이 명령문이 평가 될 때 아직 파일 file
이 아닙니다).
파이프 라인의 각 명령은 새로운 프로세스이기 때문에 고유 한 STDERR
(및 STDOUT
) STDOUT
집니다. 리디렉션이 전체 파이프 라인에 영향을 줄 것으로 예상되는 경우 이는 놀라운 결과를 생성 할 수 있습니다. 예를 들어 다음과 같은 명령 (읽기 쉽도록 줄 바꿈) :
$ python -c 'import sys;print >> sys.stderr, "Python error!"' \
| cut -f1 2>> error.log
"Python error!"가 출력 될 것입니다. 로그 파일이 아닌 콘솔에 저장하십시오. 대신 캡처 할 명령에 오류를 첨부하십시오.
$ python -c 'import sys;print >> sys.stderr, "Python error!"' 2>> error.log \
| cut -f1
표준 출력 방향 재 지정
>
현재 명령의 표준 출력 (일명 STDOUT
)을 파일이나 다른 설명 STDOUT
리디렉션합니다.
이 예제는 ls
명령의 출력을 file.txt
파일에 씁니다.
ls >file.txt
> file.txt ls
대상 파일이 없으면 작성되고, 그렇지 않으면이 파일이 잘립니다.
기본 리디렉션 설명자는 표준 출력이거나 지정되지 않은 경우 1
입니다. 이 명령은 명시 적으로 표시된 표준 출력의 이전 예제와 동일합니다.
ls 1>file.txt
참고 : 리디렉션은 실행 된 명령이 아니라 실행 된 셸에서 초기화되므로 명령 실행 전에 완료됩니다.
STDIN 리디렉션
<
오른쪽 인수에서 읽고 왼쪽 인수에 씁니다.
에 파일을 기록 할 STDIN
우리가 읽어야 /tmp/a_file
쓰기로 STDIN
즉, 0</tmp/a_file
참고 : 내부 파일 기술자 기본값으로 0
( STDIN
)에 대한 <
$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c
STDOUT 및 STDERR 모두 리디렉션
0
과 1
같은 파일 기술자는 포인터입니다. 리디렉션을 통해 가리키는 파일 설명자를 변경합니다. >/dev/null
은 1
이 /dev/null
가리킨다는 것을 의미합니다.
먼저 1
( STDOUT
)을 /dev/null
로 지정하고 2
( STDERR
)를 가리키면 1
가리 킵니다.
# STDERR is redirect to STDOUT: redirected to /dev/null,
# effectually redirecting both STDERR and STDOUT to /dev/null
echo 'hello' > /dev/null 2>&1
이것은 다음과 같이 더 짧아 질 수 있습니다 :
echo 'hello' &> /dev/null
그러나 POSIX와 충돌하고 구문 분석의 모호성을 야기하며,이 기능이없는 셸에서는이를 잘못 해석 할 수 있으므로 셸 호환이 문제가되는 경우이 양식이 생산에 바람직하지 않을 수 있습니다.
# Actual code
echo 'hello' &> /dev/null
echo 'hello' &> /dev/null 'goodbye'
# Desired behavior
echo 'hello' > /dev/null 2>&1
echo 'hello' 'goodbye' > /dev/null 2>&1
# Actual behavior
echo 'hello' &
echo 'hello' & goodbye > /dev/null
참고 : &>
는 Bash 및 Zsh에서 원하는대로 작동하는 것으로 알려져 있습니다.
STDERR 리디렉션
2
는 STDERR
입니다.
$ echo_to_stderr 2>/dev/null # echos nothing
정의 :
echo_to_stderr
는 "stderr"
를 STDERR
쓰는 명령입니다.
echo_to_stderr () {
echo stderr >&2
}
$ echo_to_stderr
stderr
잘라내 기와 대괄호 추가
자르기 >
- 지정된 파일이 없으면 작성하십시오.
- 잘라 내기 (파일 내용 제거)
- 파일에 쓰기
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines
$ cat /tmp/lines
second line
추가 >>
- 지정된 파일이 없으면 작성하십시오.
- 파일 추가 (파일 끝에 쓰십시오).
# Overwrite existing file
$ echo "first line" > /tmp/lines
# Append a second line
$ echo "second line" >> /tmp/lines
$ cat /tmp/lines
first line
second line
성병, 성병 및 성병 설명
명령에는 하나의 입력 (STDIN)과 두 종류의 출력, 표준 출력 (STDOUT) 및 표준 오류 (STDERR)가 있습니다.
예 :
성
root@server~# read
Type some text here
표준 입력은 프로그램에 입력을 제공하는 데 사용됩니다. (여기에 우리가 사용하고있는 read
내장 STDIN에서 한 줄을 읽을 수 있습니다.)
성령
root@server~# ls file
file
표준 출력은 일반적으로 명령의 "정상"출력에 사용됩니다. 예를 들어, ls
는 파일을 나열하므로 파일은 STDOUT으로 전송됩니다.
성병
root@server~# ls anotherfile
ls: cannot access 'anotherfile': No such file or directory
표준 오류는 이름에서 알 수 있듯이 오류 메시지에 사용됩니다. 이 메시지는 파일 목록이 아니기 때문에 STDERR로 전송됩니다.
STDIN, STDOUT 및 STDERR은 세 가지 표준 스트림입니다. 쉘은 이름이 아닌 숫자로 식별됩니다.
0 = 표준 in
1 = 표준 출력
2 = 표준 오류
기본적으로 STDIN은 키보드에 연결되며 STDOUT 및 STDERR이 터미널에 나타납니다. 그러나 우리는 STDOUT 또는 STDERR 중 필요한 것을 리디렉션 할 수 있습니다. 예를 들어 표준 출력 만 필요하고 표준 오류에 인쇄 된 모든 오류 메시지는 표시하지 말아야한다고 가정 해 봅시다. 그 때 우리는 기술자 1
과 2
사용합니다.
STDERR을 / dev / null로 리디렉션
앞의 예제를 보면,
root@server~# ls anotherfile 2>/dev/null
root@server~#
이 경우 STDERR이 있으면 / dev / null (아무것도 넣지 않는 특수 파일)로 리디렉션되므로 셸에서 오류 출력을 얻지 못합니다.
여러 파일을 동일한 파일로 재 지정
{
echo "contents of home directory"
ls ~
} > output.txt
명명 된 파이프 사용
때로는 하나의 프로그램으로 뭔가를 출력하고 다른 프로그램에 입력하고 싶지만 표준 파이프를 사용할 수없는 경우가 있습니다.
ls -l | grep ".log"
임시 파일에 간단히 쓸 수 있습니다.
touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt
이것은 대부분의 응용 프로그램에서 잘 작동하지만, 누구도 tempFile
이 무엇을하는지 알지 못할 것이고 누군가가 그 디렉토리에 ls -l
의 출력을 포함하고 있다면 제거 할 수도 있습니다. 이것은 명명 된 파이프가 작동하는 곳입니다.
mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe
myPipe
는 기술적으로 파일입니다 (모든 것이 Linux에 있습니다). 그래서 방금 파이프를 생성 한 빈 디렉토리에서 ls -l
을 실행합시다 :
mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l
출력은 다음과 같습니다.
prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe
사용 권한의 첫 번째 문자가 파일이 아니라 파이프로 나열됩니다.
이제 시원한 것을 해보 죠.
하나의 터미널을 열고 디렉토리를 적어 두거나 (또는 정리하기 쉬운 하나를 만들어) 파이프를 만드십시오.
mkfifo myPipe
이제 파이프에 무엇인가 넣으십시오.
echo "Hello from the other side" > myPipe
이걸 알면 파이프의 다른 쪽은 여전히 닫혀 있습니다. 파이프의 다른면을 열고 그 재료를 통과 시키자.
다른 터미널을 열고 파이프가있는 디렉토리로 가십시오 (또는 파이프를 알면 파이프에 추가하십시오).
cat < myPipe
hello from the other side
출력 한 후 두 번째 터미널에서와 마찬가지로 첫 번째 터미널의 프로그램이 완료됨을 알 수 있습니다.
이제 역순으로 명령을 실행하십시오. cat < myPipe
로 시작한 다음 그 안에 뭔가를 반복하십시오. 프로그램은 종료되기 전에 파이프에 입력 될 때까지 기다릴 것이기 때문에 여전히 작동합니다. 뭔가를 얻어야한다는 것을 알고 있기 때문입니다.
명명 된 파이프는 터미널간에 또는 프로그램간에 정보를 이동하는 데 유용 할 수 있습니다.
파이프는 작습니다. 일단 가득 차게되면, 일부 판독기가 내용을 읽을 때까지 작성기가 차단되므로 다른 터미널에서 판독기와 작성기를 실행하거나 백그라운드에서 하나 또는 다른 하나를 실행해야합니다.
ls -l /tmp > myPipe &
cat < myPipe
명명 된 파이프를 사용하는 추가 예제 :
예제 1 - 같은 터미널 / 같은 쉘에있는 모든 명령
$ { ls -l && cat file3; } >mypipe & $ cat <mypipe # Output: Prints ls -l data and then prints file3 contents on screen
예제 2 - 동일한 터미널 / 동일한 쉘에있는 모든 명령
$ ls -l >mypipe & $ cat file3 >mypipe & $ cat <mypipe #Output: This prints on screen the contents of mypipe.
file3
첫 번째 내용이 표시된 다음ls -l
데이터가 표시됩니다 (LIFO 구성).예제 3 - 동일한 터미널 / 동일한 쉘에있는 모든 명령
$ { pipedata=$(<mypipe) && echo "$pipedata"; } & $ ls >mypipe # Output: Prints the output of ls directly on screen
변수 염두
$pipedata
사용하기 때문에 주요 터미널 / 메인 쉘의 사용을 사용할 수 없습니다&
서브 쉘을 호출하고$pipedata
이 서브 쉘에서만 사용할 수있었습니다.예제 4 - 동일한 터미널 / 같은 쉘에있는 모든 명령
$ export pipedata $ pipedata=$(<mypipe) & $ ls -l *.sh >mypipe $ echo "$pipedata" #Output : Prints correctly the contents of mypipe
이것은 변수의 익스포트 선언으로 인해 메인 쉘에서
$pipedata
변수의 값을 올바르게 출력합니다. 주 터미널 / 주 쉘은 배경 셸 (&
) 호출로 인해 걸려 있지 않습니다.
오류 메시지를 stderr에 인쇄하십시오.
오류 메시지는 일반적으로 디버깅 목적이나 풍부한 사용자 환경을 제공하기 위해 스크립트에 포함됩니다. 다음과 같은 오류 메시지를 작성하기 만하면됩니다.
cmd || echo 'cmd failed'
간단한 경우에는 효과가 있지만 일반적인 방법은 아닙니다. 이 예에서 오류 메시지는 stdout
에서 오류와 성공적인 출력을 혼합하여 스크립트의 실제 출력을 오염시킵니다.
즉, 오류 메시지는 stdout
아닌 stderr
로 가야합니다. 그것은 매우 간단합니다 :
cmd || echo 'cmd failed' >/dev/stderr
다른 예시:
if cmd; then
echo 'success'
else
echo 'cmd failed' >/dev/stderr
fi
위의 예제에서 stdout
에 성공 메시지가 출력되고 stderr
에 오류 메시지가 stderr
됩니다.
오류 메시지를 인쇄하는 더 좋은 방법은 함수를 정의하는 것입니다.
err(){
echo "E: $*" >>/dev/stderr
}
이제 오류를 인쇄해야 할 때 :
err "My error message"
네트워크 주소로의 리다이렉션
Bash는 일부 경로를 특별하게 취급하며 /dev/{udp|tcp}/host/port
에 기록하여 네트워크 통신을 수행 할 수 있습니다. Bash는 청취 서버를 설정할 수는 없지만 연결을 시작할 수 있으며 TCP는 최소한 결과를 읽을 수 있습니다.
예를 들어 간단한 웹 요청을 보내려면 다음을 수행하십시오.
exec 3</dev/tcp/www.google.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3
www.google.com
의 기본 웹 페이지 결과가 stdout
출력으로 인쇄됩니다.
비슷하게
printf 'HI\n' >/dev/udp/192.168.1.1/6666
HI\n
을 포함하는 UDP 메시지를 192.168.1.1:6666
의 수신기로 보냅니다.