Можем ли мы иметь больше файловых дескрипторов, кроме обычных stdin / stdout / stderr (0, 1, 2)? - PullRequest
6 голосов
/ 18 января 2012

Можем ли мы присвоить любому файлу номер дескриптора файла?

Ответы [ 3 ]

6 голосов
/ 18 января 2012

Да, вы можете. Но это зависит от программы, если она что-то делает с ней.

$ cat fd.c 
int main()
{
    write(5,"test\n",5);
}
$ gcc fd.c
$ ./a.out 5> file
$ cat file
test
$ ./a.out 5>&1
test
$ ./a.out 
$ 

В последнем случае вывод на fd 5. исчез.

openssl использует это, чтобы разрешить парольные фразы и тому подобное, передаваемые процессу, без использования обычных argv (которые могут их выставить).

обновление регистр ввода:

$ cat fd_in.c 
int main()
{
    unsigned char buf[16];
    write(5,buf,read(6,buf,16));
}
$ gcc fd_in.c 
$ ./a.out 6< file 5>&1
test

(file содержит test\n из предыдущего примера)

3 голосов
/ 18 января 2012

Да, в bash вы можете использовать file descriptor для чтения и / или записи и можете использовать любое число. Однако , поскольку 0 , 1 и 2 используется для STDIN , STDOUT и STDERR , мы избегаем этого.Кроме того, числа больше, чем 9 используются внутри, поэтому мы стараемся их избегать.

Вот как мы можем открыть дескриптор файла, чтобы сделать следующее:

Чтение:

fd<source

Запись:

fd>source

Чтение /Напишите:

fd<>source

, где fd - это цифра, которая описывает file descriptor, а source может быть либо file, либо даже file descriptor (хотя вы бы добавили & перед ним).

Если вы используете exec для файловых дескрипторов, то это позволяет изменениям вступить в силу в текущей оболочке.В противном случае они являются локальными для функции или цикла.

Пример 1 -

Следующее использование fd будет локальным для цикла while, и вы не сможете использовать его снаружи:

while read line <&3; do 
    echo $line; 
done 3<test.file

Пример 2 -

Следующее использование fd будет видно в текущей оболочке

exec 3<test.file
while read line <&3; do 
    echo $line; 
done
1 голос
/ 18 января 2012

Как вы отметили это с помощью bash, см. AdvancedBash для ознакомления с основами.

В разделе под этой ссылкой (пример 20-2) есть следующее

LOGFILE=logfile.txt
exec 6>&1           # Link file descriptor #6 with stdout.
                    # Saves stdout.
exec > $LOGFILE     # stdout replaced with file "logfile.txt".

Это то, что вы ищете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...