У меня есть пользовательский скрипт bash, который каким-то образом создает каталог и выводит его путь. Он может работать разными способами, например, он может клонировать git-репозиторий, выполнить некоторые настройки и затем вывести путь. Что-то вроде этого:

git clone ...repo --quiet && echo "...path"

Я запускаю его, используя подстановку команд, оборачивая $(...) и используя полученный путь. Что-то вроде этого:

path=$(...)

Сама команда предоставляется пользователем, так что это может быть что угодно, я не могу ожидать, что это всегда будет git clone.

Это работает хорошо, но если команды перед финальным echo выводом что-то выводят, это испортит результат. Я мог перенаправить stdout в stderr для всех предыдущих команд и использовать только stdout на последнем шаге, но я чувствую, что это хак.

Есть ли способ оставить stdout и stderr для stdout и stderr вызывающего абонента, но иметь отдельный поток для результата?

1 ответ1

2

Это сохранит последнюю строку вывода:

path=$(whatever | tail -n 1)

Если вам нужно использовать весь вывод каким-либо образом:

  • используйте tee чтобы напечатать вывод в tty

    path=$(whatever | tee /dev/tty | tail -n 1)
    
  • или сохранить его

    path=$(whatever | tee ./file | tail -n 1)
    
  • или обработать его (и распечатать в tty или файл, а не в stdout, который передает переменную)

    path=$(whatever | tee >(grep foo | wc -c >/dev/tty) | tail -n 1)
    
  • Вы даже можете отправить (разветвить) вывод во многие пункты назначения:

    path=$(whatever | tee /dev/tty ./file /some/named/fifo >(tool1) | tail -n 1)
    

Очевидно, что новая строка в отраженном пути нарушит решение.


Если вы можете изменить последнюю команду echo в предоставленном пользователем сценарии, пожалуйста, ознакомьтесь с моим ответом для подхода, использующего временные файлы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .