где создан stdin / stdout - PullRequest
       7

где создан stdin / stdout

1 голос
/ 16 декабря 2010

В c (ansi) мы говорим ввод, взятый (s / v / f) scanf и сохраняемый в stdin, так же, как мы говорим stdout.Интересно, в Linux (Unix), где они находятся, в какой папке.Или они (stdin / stdout) произвольны (то есть таких вещей не существует)

Ответы [ 5 ]

4 голосов
/ 17 декабря 2010

stdin - это FILE *, относящийся к структуре stdio (стандарт io), которая связана с файловым дескриптором 0. Файловые дескрипторы - это то, что Unix-подобные системы, такие как Linux, используют для общения с приложениями о конкретных файловых вещах. (На самом деле, я почти уверен, что Windows это делает).

Файловый дескриптор 0 может относиться к любому типу файла , но для понимания этого должен быть вызван read (это должен быть обычный файл, паровой сокет, или символьное устройство, открытое для чтения или сторона чтения канала, в отличие от файла каталога, сокета графа данных или блочного устройства).

Процессы в Unix-подобных системах наследуют дескрипторы открытых файлов от своих родительских процессов в Unix-подобных системах. Таким образом, чтобы запустить программу с установленным для stdin чем-то, кроме родительского stdin, вы должны сделать:

 int new_stdin = open("new_stdin_file, O_RDONLY);
 pid_t fk = fork();
 if (!fk) { // in the child
     dup2(new_stdin, 0);
     close(new_stdin);
     execl("program_name", "program_name", NULL);
     _exit(127); // should not have gotten here, and calling exit (without _ ) can have
                 // side effects because it runs atexit registered functions, and we
                 // don't want that here
 } else if (fk < 0) {
      // in parent with error from fork
 } else {
     // in parent with no error so fk = pid of child
 }
 close(new_stdin); // we don't need this anymore

dup2 дублирует первый аргумент дескриптора файла как второй (закрывая второй перед тем, как сделать это, если он был открыт для текущего процесса).

fork создает дубликат текущего процесса. execl - это одна из функций семейства exec, которые используют системный вызов execve для замены текущей программы другой программой. Комбинации fork и exec - это то, как программы обычно запускаются (даже если они скрыты в других функциях).

В приведенном выше примере мы могли бы запустить новую программу с установленным для stdin концом чтения канала, tty (последовательный порт / TeleTYpe) или несколькими другими вещами. Некоторые из них имеют имена, присутствующие в файловой системе, а другие - нет (например, некоторые каналы и сокеты, хотя некоторые имеют имена в файловой системе).

Linux делает /proc/self/fd/0 символической ссылкой на файл, открытый как 0 в текущем процессе. /proc/%i/fd/0, pid будет представлять символическую ссылку на то же самое для произвольного pid (ID процесса) с использованием синтаксиса printf. Эти символические ссылки часто используются для поиска реального файла в файловой системе (с использованием системного вызова readlink), но если файл фактически не существует в файловой системе, то данные ссылки (что обычно называется именем файла) вместо этого являются просто строкой это немного говорит о файле.

Здесь я должен указать, что файл, на который ссылается stdin (fd 0), даже если он находится в файловой системе, может не иметь только одного имени. У него может быть более одной жесткой ссылки, поэтому у него будет более одного имени - и каждое из них будет таким же именем, как и любая другая жесткая ссылка. Кроме того, он может вообще не иметь имени, если все его жесткие ссылки были unlinked с момента его открытия, хотя его данные будут оставаться на диске до тех пор, пока все дескрипторы открытого файла для него не будут закрыты.

Если вам на самом деле не нужно знать, где она находится в файловой системе, а просто хотите получить информацию об этом, вы можете использовать системный вызов fstat. Это похоже на stat системный вызов и утилиту командной строки, за исключением уже открытых файлов.

Все, что я сказал здесь о stdin (fd 0), должно быть применимо к stdout (fd 1) и stderr (fd 2) за исключением того, что они оба будут записываемыми, а не читаемыми.

Если вы хотите узнать больше о любой из упомянутых мной функций, обязательно посмотрите их на страницах руководства, набрав:

man fork

в командной строке. Большинство функций, о которых я упоминал, находятся в разделе 2 справочных страниц, но одна или две могут быть в разделе 1, поэтому man 2 fork также будет работать и может быть полезно, когда инструмент командной строки имеет то же имя, что и функция.

4 голосов
/ 16 декабря 2010

Это потоки, созданные для вашего процесса операционной системой. С ними не связано ни одного именованного объекта файла, и поэтому они не имеют представления в файловой системе, хотя, как указывает разматывание, к ним можно обращаться через псевдо-файловую систему, если ваш вариант UNIX поддерживает такую ​​вещь.

2 голосов
/ 16 декабря 2010

В Linux вы обычно можете найти stdin через / proc в /proc/self/fd/0, а стандартный вывод /proc/self/fd/1.

1 голос
/ 16 декабря 2010

stdin - это стандартный ввод - например, ввод с клавиатуры. stdout - стандартный вывод - например, монитор.

Для получения дополнительной информации читайте это .

0 голосов
/ 16 декабря 2010

Если вы запустите:

./myprog < /etc/passwd

, тогда stdin существует в файловой системе как /etc/passwd. Если вы просто запустите

./myprog

в интерактивном режиме в терминале, тогда stdin существует в файловой системе как то, чем является ваше терминальное устройство (вероятно, /dev/pts/5 или что-то в этом роде).

Если вы запустите

cat /etc/passwd | ./myprog

затем stdin является анонимным каналом и не имеет экземпляров в файловой системе, но Linux позволяет вам получить его через /proc/12345/fd/0, где 12345 - pid myprog.

...