
Вот скрипт для проверки источника для stdin,
из How-to Geek: «Что такое stdin, stdout и stderr в Linux?»
https://www.howtogeek.com/435903/что-есть-stdin-stdout-and-stderr-on-linux/
#!/bin/bash
if [ -t 0 ]; then
echo stdin coming from keyboard
else
echo stdin coming from a pipe or a file
fi
Тогда если какая-либо команда выполняется с аргументами или подстановкой команды, имеет ли она отношение к stdin
? В таком случае является ли stdin
пустым?
И хотя я могу понять значение " stdin
исходит из трубы" или "файла", но что означает " stdin
исходит с клавиатуры"? Это как набор клавиш для read
команды или документа здесь?
Поблагодарите сообщество за ежедневную поддержку.
решение1
Чтобы прояснить разницу между command line arguments
и stdin
. Я собираюсь разделить свой ответ на несколько частей, объясняющих основные концепции. Затем отвечу на ваш вопрос.
Прежде чем я начну объяснять, помните следующее:
- В Linux все рассматривается как файл.
- Я полагаю, что вы прочитали весь текст, приведенный в вопросе.
- Я собираюсь воспользоваться программой на языке C, чтобы объяснить разницу, поэтому я предполагаю, что вы знаете базовый синтаксис. Тем не менее, я объясню как можно больше.
аргументы stdin и командной строки
Стандартный ввод — это файл Linux, к которому обращаются программы для получения ввода от пользователя. Любая программа не может напрямую взаимодействовать с Keyboard, вместо этого они взаимодействуют с stdin
. Поэтому, если программе нужно получить ввод от пользователя, она обратится к stdin
.
Когда вы используете перенаправление ( > or <
) или конвейер ( |
) с другой командой, он манипулирует входными и выходными потоками, т.е. stdin
и stdout
. Когда вы указываете эти специальные символы, они дают указания stdin
и stdout
как функционировать. В Linux stdin
это /proc/self/fd/0
, и stdout
это/proc/self/fd/1
Аргументы командной строки — это, по сути, метод получения входных данных, используемый вместе с вызовом команды, чтобы заставить команду выполнить определенную задачу.Не обязательно, чтобы каждая программа имела аргументы командной строки., поскольку разработчик следующей программы должен решить, использовать ли их.
Аргументы командной строки передаются команде в виде массива. (Массив — это структура данных, состоящая из набора элементов, каждый из которых идентифицируется по крайней мере одним индексом массива или ключом.). Следовательно, значения в этом массиве могут использоваться программистом для добавления дополнительной функциональности в свою программу.
Примеры программ на языке C
#include<stdio.h>
int main(int argc, char *argv[]) {
if(argc==2)
printf("Welcome Master %s\n", argv[1]);
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
В приведенной выше программе не принимается стандартный ввод от пользователя, однако она принимает аргументы командной строки и работает по-разному в зависимости от того, указан аргумент или нет.
argc
— это переменная, которая хранит количество переданных аргументов, и argv
это массив, который хранит переданные аргументы при вызове программы. argv[0]
— это первый элемент в массиве, который содержит имя самой программы. После этого массив будет содержать переданные аргументы.
Когда я запускаю следующую программу, набрав «./batman», я получаю следующий вывод:
Использование: ./batman
Но когда я запускаю ту же программу, набрав "./batman Bruce", я получаю:
Добро пожаловать, Мастер Брюс.
Теперь это не значит, что эта программа не может принимать входные данные. Ниже представлена модифицированная программа, которая принимает как аргумент командной строки, так и стандартный ввод.
#include<stdio.h>
int main(int argc, char *argv[]) {
int pass = 0;
if(argc==2){
printf("Welcome Master %s\n", argv[1]);
printf("Kindly provide password : ");
scanf("%d", &pass);
if(pass==1234)
printf("Batcave Access granted\n");
else
printf("Batcave Access declined\n");
}
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
Вышеуказанный код принимает аргумент командной строки, а затем ждет, пока пользователь введет пароль через стандартный ввод.
Если мы не укажем аргумент, он выдаст ошибку, как и в предыдущем коде C.
Ниже приведен вывод при выполнении программы:
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Bruce Welcome Master Bruce Kindly provide password : 1234 Batcave Access granted mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Joker Welcome Master Joker Kindly provide password : 123 Batcave Access declined mars@HP-Notebook:~/Desktop/Practice/cpp$
После передачи аргумента командной строки эта программа ждала пароль, который должен был быть введен пользователем, следовательно, черезstdin
Какой же вывод?
Надеюсь, вы поняли концепции, которые я объяснил выше. Теперь пришло время ответить на эти вопросы.- Да, аргументы командной строки не имеют никакого отношения к
stdin
иstdin
в этом случае просто указывают на ваше устройство ввода, но не используются. stdin
сам по себе является файлом, который по умолчанию указывает на ваше устройство ввода и берет ввод оттуда. Однако, когда вы указываете канал или перенаправление в своей команде, это говоритstdin
брать ввод из указанного вами файла вместо устройства ввода, подключенного к вашему компьютеру.
Если вы не поняли программу на C, ничего страшного. На этот раз давайте воспользуемся встроенной командой вместо пользовательской программы.
Пример команды вместо программы:
cat file_name
cat < file_name
вывод будет идентичным, поскольку соответствующий разработчик делает cat
так, чтобы либо считывать данные из файла stdin
, либо считывать данные из файла, имя которого указано в качестве первого аргумента командной строки (который является первым элементом в массиве, передаваемом оболочкой в cat).
Затем cat записывает все содержимое file_name или stdin
в терминал, поскольку мы не даем оболочке указание манипулировать stdout
. Помните, что во второй строке ваша оболочка манипулирует stdin
таким образом, что она больше не указывает на ваше стандартное устройство ввода, а указывает на файл с именем file_name в вашем текущем рабочем каталоге.Этот пример взят из другого поста, вы можете нажать здесь, чтобы прочитать больше
Надеюсь, это не только дало вам ответ на вопрос, но и помогло вам понять основные концепции.