аргументы stdin и командной строки

аргументы stdin и командной строки

Вот скрипт для проверки источника для 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. Я собираюсь разделить свой ответ на несколько частей, объясняющих основные концепции. Затем отвечу на ваш вопрос.

Прежде чем я начну объяснять, помните следующее:

  1. В Linux все рассматривается как файл.
  2. Я полагаю, что вы прочитали весь текст, приведенный в вопросе.
  3. Я собираюсь воспользоваться программой на языке 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

Какой же вывод?

Надеюсь, вы поняли концепции, которые я объяснил выше. Теперь пришло время ответить на эти вопросы.

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

Если вы не поняли программу на C, ничего страшного. На этот раз давайте воспользуемся встроенной командой вместо пользовательской программы.

Пример команды вместо программы:

cat file_name
cat < file_name

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

Затем cat записывает все содержимое file_name или stdinв терминал, поскольку мы не даем оболочке указание манипулировать stdout. Помните, что во второй строке ваша оболочка манипулирует stdinтаким образом, что она больше не указывает на ваше стандартное устройство ввода, а указывает на файл с именем file_name в вашем текущем рабочем каталоге.Этот пример взят из другого поста, вы можете нажать здесь, чтобы прочитать больше

Надеюсь, это не только дало вам ответ на вопрос, но и помогло вам понять основные концепции.

Связанный контент