Почему exec {fd}

#bash

#bash

Вопрос:

Я нашел код, который получает файловый дескриптор ‘file’. Код следующий.

 exec {fd}<'file'
  

К сожалению, в коде не указано, почему он может получить файловый дескриптор с помощью exec. Даже после того, как я прочитал руководство по bash, я не мог понять, какую команду здесь выполняет exec. Кто-нибудь, кто знает механизм приведенного выше кода, пожалуйста, дайте мне знать. Большое вам спасибо.

Ответ №1:

Это немного странно.

Обычно при запуске программы можно указать перенаправления:

 cat 0<file #= cat <file
  

Это в основном создает процесс для cat fork ввода. Затем он opens file dup помещает свой filedescriptor в filedescriptor 0, а затем exec cat помещает его в дочерний элемент.

  //Equivalent C code:
 pid=fork();  
 //... (=error checking)
 if(0==pid){
      //child
      int fd; 
      fd = open("file", O_RDONLY);
      //...
      dup2(fd, 0);
      //..
      execvpl("cat", "cat", (char*)0); 
      //..
 }
  

Если бы вы вместо этого exec cat 0<file сделали это, не было бы fork редактирования,
а перенаправления и exec вызов происходили бы в текущем процессе:

 int fd; 
fd = open("file", O_RDONLY);
//...
dup2(fd, 0);
//..
execvpl("cat", "cat", (char*)0); 
//..
  

Оболочки перегружаются exec так, что, если не указана программа to exec , open dup в текущем процессе выполняются только ing и ing (которые вместе преобразуются в перенаправления оболочки).

Это позволяет перенаправлять для текущего процесса:

 exec 0<file       #standard input is the file "file" from this point forward
  

Bash и другие продвинутые оболочки расширяют это, позволяя вам использовать exec синтаксис, чтобы просто открыть файл и получить номер файлового дескриптора.

 exec {fd}<file
  

в основном это их способ сделать:

 fd = open("file", O_RDONLY);
  

Комментарии:

1. Спасибо за прекрасный подробный ответ. Наконец-то я смог понять механизм. Еще раз спасибо.

2. Рад, что это понятно. Изначально я перепутал пару деталей. Надеюсь, теперь это должно быть в основном правильно.

Ответ №2:

Специальный бит синтаксиса — это фигурные скобки вокруг идентификатора. Обычно вы указываете выражение, которое вычисляется до целочисленного значения, например

 exec 3<file   # Open file for reading on fd 3
fd=5
exec $fd<file # Open file for reading on fd 5
  

Фигурные скобки заключают имя, а не целое число, которое запрашивает оболочку найти доступный для нас дескриптор, открыть файл по этому дескриптору, затем установить имя, равное этому значению.

 # Pretend there is a function called get_avail_fd
# Then the following is something like
#     fd=$(get_available_descriptor)
#     exec $fd<file
# except there is no race condition or need to lock
# file descriptor between the call to get_avail_fd and exec
exec {fd}<file
  

Комментарии:

1. спасибо за предоставление практических знаний и использование.