Помогите объяснить это перенаправление вывода удара

find . -regex ".*/.*abc.*" быстрее потому что find . | grep ".*abc.*" должен иметь find генерируйте все данные и передайте их к grep. Разница, вероятно, будет небольшой все же. find . -regex ".*/.*abc.*" также более надежно, потому что это работает даже в редком случае, где у Вас есть имена файлов с пробелами.

Обратите внимание, что обе команды ищут файлы, полный путь которых содержит abc. Это включает не только файлы, имя которых содержит abc но также и файлы содержали в каталоге, имя которого содержит abc, рекурсивно. Найти только файлы, имя которых содержит abc, использовать

find -name '*abc*'

В ksh, ударе или zsh, можно работать echo **/*abc* вместо этого: **/ взгляды во всех подкаталогах рекурсивно. В ksh необходимо будет работать set -o globstar сначала (вставляет это Ваш ~/.kshrc). В ударе необходимо будет работать shopt -s globstar сначала (вставляет это Ваш ~/.bashrc).

3
13.04.2017, 15:36
3 ответа

Внутри $(...), stdout (fd 1) является каналом. В другом конце канала оболочка читает вывод и хранит его в $result переменная.

С: $({ blah; } 3>&1) мы делаем его что и fd 3 и 1 точка к тому каналу в blah.

blah cmd1 | cmd2. Там cmd1 и cmd2 запускаются одновременно с cmd1 fd 1, указывающий на другой канал (один к cmd2), однако мы не хотим ssh вывод для движения в тот канал мы хотим, чтобы это перешло к первому каналу так, чтобы он мог быть сохранен в $result.

Таким образом, мы имеем { ssh >&3; echo "$?"; } | cmd2, так, чтобы только echo вывод переходит к каналу к cmd2. ssh вывод (fd 1) переходит в $result. ssh не нуждаясь в fd 3, мы закрываем его для него после того, как мы использовали его для установки fd 1 (3>&-).

cmd2вход (fd 0) является вторым каналом. Ничто не пишет в тот канал (так как ssh пишет в первый канал) до ssh завершается и echo производит статус выхода там.

Таким образом в cmd2 (быть until цикл), read -t1 на самом деле ожидает с тайм-аутом до ssh выходы. После которого, read возвратится успешно с содержанием $? питаемый echo.

4
27.01.2020, 21:16
  • 1
    Argh удара! Я вижу, ssh действительно переходит к исходному stdput и приводит к результату, который является тем, что Вы хотите, и ничто не отправляется через канал ssh, только echo $? из ssh. :-) очень умный! Мне нравится тайм-аут цикла чтения также. спасибо –  X Tian 06.02.2014, 14:56

Хорошо, во-первых что происходит, если Вы выполняете удаленную команду через ssh

ssh  otherhost /bin/true; echo $?
0

и

ssh otherhost /bin/false; echo $?
1

так echo "$?" печатает возвращаемое значение app-status к stdout (дескриптор файла 1)

  1. Внешнее {...} 3>&1 перенаправления весь вход от дескриптора файла 3 до stdout
  2. >&3 3>&- перенаправления stdout к дескриптору файла 3 и дескриптору файла 3 завершений.
  3. read -t1 ret вход чтений от stdin до переменной ret
  4. printf . >&2 печать . к stderr (дескриптор файла 2)

Хорошее чтение Усовершенствованное Руководство по созданию сценариев Bash

1
27.01.2020, 21:16

Основная идея позади voodo перенаправлений fd 3 к fd 1 и fd 1 к fd 3 в команде группы { ... 1>&3 3>&- ...} 3>&- 3>&1 должен сделать вывод ssh управляйте обходят ssh | until канал через fd 3.

Что-либо записанное в fd 3 в группе управляет с 1>&3 обойдет механизм канала.

Этот путь read команда (который "возвратит отказ, если полная строка входа не будет считана в течение секунд ТАЙМ-АУТА", посмотрите help read в ударе), только доберется для чтения статуса выхода ssh команда и вывод, присвоенный result переменная может быть ограничена выводом ssh команда.

# examples for bypassing a pipe using output redirections

# cf. http://unix.stackexchange.com/a/18711
echo hello | sed 's/hello/HELLO/'
{ echo hello 1>&3 3>&- | sed 's/hello/HELLO/'; } 3>&- 3>&1

{
result=$(
  {
    {
      ssh localhost 'sleep 5; echo "ssh output"; exit 55' >&3 3>&-; echo "$?"
    } | {
      until read -t1 ret; do
        printf . >&2
      done
      printf '\n%s\n' "exit $ret" >&2
      exit "$ret"
    }
  } 3>&1
)
echo "result: $result"
}

# output:
# .....
# exit 55
# result: ssh output

И наконец, что не менее важно, дублирование stdout потока сделано man 1 tee, не перенаправлениями вывода. Внешнее {...} 3>&1 перенаправление означает, что fd 3 открыт и указывает туда, где fd 1 указывает, т.е. к stdout.

Дальнейшее чтение:

0
27.01.2020, 21:16

Теги

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