Linux Descriptor 편집

[참고문서]
http://www.tldp.org/LDP/abs/html/io-redirection.html

exec 3<> /tmp/foo # open fd 3.
echo a >&3 # write to it
exec 3>&- # close fd 3.

 

Closing File Descriptors

n<&-
Close input file descriptor n.

0<&-, <&-
Close stdin.

n>&-
Close output file descriptor n.

1>&-, >&-
Close stdout.

&>
표준출력, 표준에어를 모두 특정 파일에 모두 출력하라는 의미

user1@user1-900X3L:~/Downloads/test$ moe 1>sample
moe라는 명령어는 없다. 따라서 출력은 표준에러 2번으로 간다. 그런데 1>sample 이렇게 하면 화면에 표준에러 내용들이 출력되는 것을 확인할수 있다.
즉, 에러는 따로 리다이렉트 한것이 없으므로 그대로 나온다.
user1@user1-900X3L:~/Downloads/test$ moe 2>sample
에러를 sample 파일로 리다이렉트 했다. 따라서 콘솔 화면에는 아무것도 나오지 않게 된다.
user1@user1-900X3L:~/Downloads/test$ moe &>sample
에러든 출력이던 아무것도 나오지 않게 된다.

 

3>&1 1>&2 2>&3의 의미 – it swaps stdout with stderr)

표준출력을 표준에러로 바꿔서 출력하라는 것
3>&1 : 3번 디스크립트를 열어서 1번 표준출력으로 가라고 명령
1>&2 : 1번 표준출력의 내용을 2번 표준에러로 가라고 명령
2>&3 : 2번 표준에러의 내용을 3번 디스크립트로 가라고 명령

[디스크립터번호]가 나오고 이후에 바로 >,<,<> 리다이렉트 연산자가 나온후 연결할 것(&1)인지 닫을것(&-)인지 결정한다.
* 0번은 표준입력 stdin을 의미한다.
* 1번은 표준출력 stdout을 의미한다.
* 2번은 표준에러 stderr을 의미한다.

표준입력0, 표준출력1, 표준에러2 활용방법

exec 3>&1 : 기존에는 /proc/nnnn/fd/3 proc가 없다. 이상황에서 3번 파일디스크립터를 연다.
grep Comment examples.dektop 2>/dev/null 이러한 식으로 해당 출력이 "표준출력"인지 "표준에러"인지 알아낸다.
exec 3<> aaa : 3번 FD를 aaa와 연결한다.
webterror@mlinkkorea-webterror:~$ echo "djfkldsajkf" >&3
webterror@mlinkkorea-webterror:~$ cat aaa
djfkldsajkf
webterror@mlinkkorea-webterror:~$ echo "djfkldsajkf" >&3
webterror@mlinkkorea-webterror:~$ cat aaa
djfkldsajkf
djfkldsajkf
webterror@mlinkkorea-webterror:~$ echo "djfkldsajkf" >&3
webterror@mlinkkorea-webterror:~$ cat aaa
djfkldsajkf
djfkldsajkf
djfkldsajkf
exec 3>&- : 3번 파일디스크립터를 닫는다.

# IO redirection for logging.

touch $LOGFILE
exec 6>&1 # Link file descriptor #6 with stdout.
# Saves stdout.
exec > $LOGFILE # stdout replaced with file $LOGFILE.

touch $LOGERR

exec 7>&2 # Link file descriptor #7 with stderr.
# Saves stderr.
exec 2> $LOGERR # stderr replaced with file $LOGERR.

 

이해 해야 하는 것

user1@user1-900X3L:~/Downloads/test$ echo 1234567890 > File
user1@user1-900X3L:~/Downloads/test$ exec 3<> File
user1@user1-900X3L:~/Downloads/test$ read -n 4 <&3
user1@user1-900X3L:~/Downloads/test$ echo -n . >&3
user1@user1-900X3L:~/Downloads/test$ exec 3>&-
user1@user1-900X3L:~/Downloads/test$ cat File
1234.67890

 

while문 밖에서 디스크립터를 열어 활용하는 방법

while read -u 3 line
do
command1
command2
done 3< <(tail -f /path/file.txt)
Or, if you want to do the exec:

exec 3< <(tail -f /path/file.txt)

while read -u 3 line
do
command1
command2
done

 

user1@user1-900X3L:~/Downloads/test$ exec 3<sample ==> 처음의 exec 실행시 sample 파일의 내용을 모두 3번 디스크립터로 옮긴다.
user1@user1-900X3L:~/Downloads/test$ cat <&3 ==> 디스크립터에 있는 내용을 읽어서 출력한다.
File
sample
File
sample
File
sample
File
sample
user1@user1-900X3L:~/Downloads/test$ cat <&3 ==> 디스크립터에 있는 커서가 맨 뒤로 이동 되어 있으므로 이후의 cat 내용은 나오지 않게 된다.

 

<(xxxx) 의 의미

user1@user1-900X3L:~/Downloads/test$ echo <(echo "abcd")
/dev/fd/63 ==> 즉, 디스크립터 위치를 알려주게 된다.

user1@user1-900X3L:~/Downloads/test$ cat <(echo "abcd")
abcd ==> 따라서 위의 의미는 cat /dev/fd/63 의 커맨드와 동일한 표기이다.

[예제] exec 4< <(sort -R list.txt)

<(sort -R list.txt) = “/dev/fd/63″로 대체됨
이후 “exec 4< /dev/fd/63″로 바뀌지만, “exec 4<<(sort -R list.txt)”로 작성할수 없는 이유는 “<<” 연산자로 바뀌어 인식되는 점과, 최종 “4< /dev/fd/63” 모습으로 바꿀수 없기 때문에,
“<” 연산자를 따로 스페이스를 넣어 구분하는 것이다. 결론적으로 “exec 4</dev/fd/63” 이러한 모습으로 바뀌어 4번 디스크립터에 read된 내용을 저장하게 되는 셈이다.
새로운 디스크립터를 열었을 경우의 이해 [중요]

user1@user1-900X3L:~/Downloads/test$ cat sample
abcd
user1@user1-900X3L:~/Downloads/test$ exec 4<sample 
==> 4번 디스크립터를 입력용으로 새롭게 열어준다. 즉, read등의 입력또는 cat으로 입력 리다이렉트로 쓰지 않는한 다른 것에는 활용이 제한된다.

user1@user1-900X3L:~/Downloads/test$ cat <&4
abcd
user1@user1-900X3L:~/Downloads/test$ cat <&4
user1@user1-900X3L:~/Downloads/test$ 
==> 첫번째 cat <&4 커맨드에서는 4번 디스크립터를 읽고 화면에 출력하지만, 두번째 cat에서는 아무것도 출력을 하지 못한다. 이유는 모두 읽고 데이터가 없기 때문이다.

user1@user1-900X3L:~/Downloads/test$ exec 4<sample 
user1@user1-900X3L:~/Downloads/test$ cat <&4 | xargs -I vars echo vars
abcd
==> 다시 4번 디스크립터에 sample의 결과 "abcd"를 넣고 파이프를 이용하여 표준출력을 표준입력으로 바꾸어서 xargs의 -I 옵션으로 var변수에 담아 출력을 해보면 "abcd"가 그대로 출려되는 것을 알수있다.
즉, 파이프는 표준출력을 표준입력으로 바꿔주는 역할을 한다고 보면 된다.

user1@user1-900X3L:~/Downloads/test$ exec 4<>sample 
==> "<>" 연산자를 사용하면 해당 디스크립터를 읽고 쓸수 있게 해준다.

user1@user1-900X3L:~/Downloads/test$ echo -e "12345\n12345" >sample
user1@user1-900X3L:~/Downloads/test$ exec 4<>sample 
user1@user1-900X3L:~/Downloads/test$ echo "abcd" >&4
user1@user1-900X3L:~/Downloads/test$ exec 4>&-
user1@user1-900X3L:~/Downloads/test$ cat sample
abcd
12345

(1) 최초 “sample” 파일을 뉴라인과 함께 넣어 “12345\n12345″로 기록한다.
(2) 4번 파일을 sample 파일에 할당한다. 이 시점에서 4번 디스크립터에는 “12345\n12345″가 동일하게 기록되어 있다. (입력 디스크립터로 생성되었기에 이시점에서 cat으로 확인하는 순간 모두 증발한다.)
(3) “abcd\n” newline까지 포함 텍스트가 4번 디스크립터에 첫번째 라인을 덮어쓰게 된다. 이시점에서 4번 디스크립터에는 abcd의 4글자를 읽어내고 newline을 대체하는 순간 “\n12345″만 남게 된다.
이후 sample파일에는 “동일한 위치로 “abcd\n”내용이 “12345”와 교체되면서 “abcd\n\n12345″로 남게 된다.
(4) 4번 디스크립터를 닫는다.
(5) cat으로 sample 파일을 확인한다.

관련 글

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다