Как получить дескриптор файла кроме stdin stdout и stderr (чтобы сделать что-то как программа 1$> file_1 3> file_2)?

Добавление ненулевого возвращаемого значения последней команды является прекрасной идеей. Я думаю, что исходный плакат конкретно спрашивал о .profile/.cshrc/.bashrc. Стоит упомянуть список других обычно специализированных файлов RC, но я придерживался бы просто настроек оболочки для этого вопроса.

Я также недавно добавил флаг в своей подсказке, которая обнаруживается, когда оболочка работает под экраном. Это использует solaris "ptree" команда для поиска процессов предка, но Вы могли использовать команду "pstree" на Linux, чтобы сделать то же самое.

SCREEN=""
if [ -f /usr/bin/ptree ]; then
   if ptree $$ | grep -v grep | grep -w screen > /dev/null 2>&1; then
       SCREEN="SCREEN "
   fi
fi

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

PROMPT_COMMAND='if [ "$?" = 0 ]; \
        then RC=""; \
        else RC="RV=$? "; fi; PS1="% ${SCREEN}\h $RC\w\n% "'

Я уверен, что это могло быть сделано более красивым.:-)

Будущая подсказка, быть осторожным относительно чтения $? после использования, "если [". Если левая скобка будет встроенным, то она не переопределит значение $?. Но если Вы будете использовать оболочку, где [не встроено, затем она сбросит значение $? после тестирования. Более безопасно присвоить $? во временную переменную сразу же и затем тестируют ту переменную.

6
18.12.2011, 19:33
3 ответа

Вы можете, но это не хорошая идея. Обычно программы запускаются с трех открытых дескрипторов файлов:

  • 0 стандартный вход, где команды, что текст процесса в некотором роде считал вход, если он не прибывает из файла.
  • 1 стандартный вывод, для нормальных данных, произведенных командой, если данные явно не идут в файл.
  • 2 стандартная погрешность, для сообщений диагностики, которые не являются частью полезных данных, произведенных командой.

Можно нарушить эти конвенции и использовать больше дескрипторов файлов, но это означает, что приложение только будет непосредственно применимо в среде, где вызывающая сторона указала правильные дескрипторы файлов. Вы легко не сможете протестировать на это в своем приложении: так как дескрипторы файлов 3 и выше не отрегулированы, они могут быть закрыты, когда Ваше приложение запускается (это может быть обнаружено), или они могут быть открыты для некоторой несвязанной цели (это не может быть обнаружено).

Передача имен файлов на командной строке является нормальным способом указать несколько файлов ввода или вывода.

Однако для доступа к произвольным дескрипторам файлов:

  • В оболочке: перенаправьте к желаемому числу, например.

    IFS= read -r line <&3
    printf "%s\n" "$line" >&4
    
  • В C звонить read или write с любым fd Вы хотите, или вызов fdopen получить stdio поток.
  • В Perl укажите перенаправление оболочки как имя файла для открытия, чтобы копировать дескриптор файла или добавить = сделать плоскость fdopen.

    open IN3, "<&=3";
    open OUT4, ">&=4";
    
  • В Python звонить os.fdopen.
11
27.01.2020, 20:22

Да, Вы, конечно, можете.Примечание: 1>file_1 может быть упрощен до >file_1 как 1 значение по умолчанию.

Например:

$ cat test.ksh
#!/bin/ksh
echo "this goes to stdout" 
echo "this goes to stderr" >&2
echo "this goes to fd 3" >&3
$ ./test.ksh >file_1 3>file_2
this goes to stderr
$ cat file_1
this goes to stdout
$ cat file_2
this goes to fd 3
3
27.01.2020, 20:22

Можно перенаправить произвольные дескрипторы файлов в оболочке точно как шоу в качестве примера. Программам, которые работают с несколькими потоками, нужно сказать названия файлов для использования. Если Вы действительно хотите иметь использование программы fd, Вы перенаправили с оболочкой (возможно, к каналу), затем передают его /dev/fd/N чтобы имя файла заставило это использовать fd N.

1
27.01.2020, 20:22

Теги

Похожие вопросы