일반적인 방법으로 파일 설명자를 명시적으로 열 수 있습니다.
$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:06 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:06 1 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:06 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:06 3 -> /proc/31288/fd
$ exec 3<foo
$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:07 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:07 1 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:07 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:07 3 -> /home/tavianator/foo
lr-x------ 1 tavianator users 64 Jul 10 11:07 4 -> /proc/31334/fd
여태까지는 그런대로 잘됐다. zsh
두 자리 파일 설명자 구문은 지원되지 않는 것 같지만 10<foo
변수 대체 구문은 지원합니다 {fd}<foo
.
$ fd=10
$ exec {fd}<foo
$ ls -lh /dev/fd/
total 0
lrwx------ 1 tavianator users 64 Jul 10 11:08 0 -> /dev/pts/6
lrwx------ 1 tavianator users 64 Jul 10 11:08 1 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:08 11 -> /home/tavianator/foo
lrwx------ 1 tavianator users 64 Jul 10 11:08 2 -> /dev/pts/6
lr-x------ 1 tavianator users 64 Jul 10 11:08 3 -> /home/tavianator/foo
lr-x------ 1 tavianator users 64 Jul 10 11:08 4 -> /proc/31413/fd
그런데 잠깐, 왜 fd야?11대신에 열다10?
답변1
그것이 ZSH가 작성된 방식이기 때문입니다. 기본적으로 ZSH는 파일 설명자를 fd 10에 복사합니다.
$ PS1='%% ' zsh -f
% lsof -p $$ | grep 10u
zsh 29192 jhqdoe 10u CHR 136,0 0t0 3 /dev/pts/0
%
Src/exec.c
후속 호출의 fd 관련 코드movefd
/**/
static void
addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
char *varid)
{
int pipes[2];
if (varid) {
/* fd will be over 10, don't touch mfds */
fd1 = movefd(fd2);
if (fd1 == -1) {
zerr("cannot moved fd %d: %e", fd2, errno);
return;
다음으로 Src/utils.c
사용 가능한 10개 이상은 이미 기본적으로 취해진 것이므로 첫 번째로 볼 수 있는 것은 11개 항목을 반복합니다.
movefd(int fd)
{
if(fd != -1 && fd < 10) {
#ifdef F_DUPFD
int fe = fcntl(fd, F_DUPFD, 10);
#else
int fe = movefd(dup(fd));
#endif
내 zsh
기준은 코드 경로를 strace
사용하고 있지만 zsh는 기본적으로 해당 번호에 중복을 저장하기 때문에 11에서 시작하는 새 fd를 사용할 수 없다는 의견이 있습니다 .fcntl
fcntl(...
movefd(dup(...
이 모든 {somelabel}
작업은 10보다 큰 사용 가능한 가장 낮은 파일 설명자를 얻는 것입니다. 이는 쉘이 열려 있는 다른 항목에 따라 11이거나 더 높은 숫자일 수 있습니다.
% exec {foo}>asdf
% echo $foo
11
% exec {quer}>asdf
% echo $quer
12
...