2015-10-19 5 views
3

bash pipe questionВыход трубы bash для нескольких процессов

Я видел похожие вопросы с ответами, но я спрашиваю о самом базовом случае вывода трубопровода на несколько процессов. Например, я хочу вывести состояние в cowsay и (espeak &). У меня есть решение (следующее), но должен быть более простой и элегантный способ.

Joshua @ Joshua-HP-Pavilion-dv8-Notebook-PC ~ $ кошка .bashrc

(fortune -a > ~/tmp) && echo && (cat ~/tmp |cowsay -W65) && (cat ~/tmp | espeak &) 
rm ~/tmp 

Выход:

___________________________________________ 
/I ain't got no quarrel with them Viet Congs. \ 
|            | 
\ -- Muhammad Ali       /
---------------------------------------------- 
     \ ^__^ 
     \ (oo)\_______ 
      (__)\  )\/\ 
       ||----w | 
       ||  || 
[email protected] ~ $ 

Plus аудио из озвучки работает как фоновый процесс (| espeak &). Мое решение перенаправляет вывод в файл (~/tmp), выполняет действия, а затем удаляет ~/tmp. Почему я не могу это сделать, например:

fortune -a | (cowsay -W70 && espeak &) 

? Я пробовал много вариантов, вот моя история попыток:

501  fortune -a | (cowsay -W70 && espeak &) 
    502  fortune -a | (cowsay -W70 && espeak) 
    503  fortune -a | (cowsay -W70 | espeak) 
    504  fortune -a | (cowsay -W70; espeak) 
    505  fortune -a | (espeak | cowsay -W70; espeak) 
    506  fortune -a | (espeak | cowsay -W70) 
    507  fortune -a | (espeak & | cowsay -W70) 
    508  fortune -a | (espeak & && cowsay -W70) 
    509  fortune -a | (espeak && cowsay -W70) 
    510 fortune -a | (espeak && cowsay -W70) 
    511 (fortune |cowsay -W65) && (cat ~/tmp | espeak &) 
    512 (fortune |cowsay -W65) && (espeak &) 
    513 (fortune |cowsay -W65) && espeak & 
    514 fortune | (cowsay -W65 && espeak &) 
    515 history 

Кроме того, это моя первая попытка разместить вопрос. Добро пожаловать!

ответ

1

Почему бы не позвонить fortune -a once и сохранить его результаты в переменной?

# Store "fortune" output in a variable 
fortune_result=$(fortune -a) 

# Use that variable as input for multiple processes 
(cowsay -W70 && espeak &) <<< "$fortune_result" 
(cowsay -W70 && espeak) <<< "$fortune_result" 
(cowsay -W70 | espeak) <<< "$fortune_result" 
+0

Мне нравится переменная идея. Избегание дискового ввода-вывода, особенно для нескольких строк текста, всегда является хорошей идеей. – user2085548

1

Прежде всего, надобно ответить на этот вопрос, и я рад, что вы попробовали, прежде чем приходить сюда и спрашивать. Мне было очень весело, когда я увидел выход :) - Upvoted.

Мой лучший результат до сих пор (и я думаю, что это более проще, чем у вас)

fortune -a > a.txt | cowsay && espeak -f a.txt && rm a.txt 

Логика я использовал:

  • состояние в файл
  • трубы, чтобы результат cowsay & & espeak
  • удалить файл.
+0

Спасибо! Мне пришлось немного подправить его, потому что я сразу же хочу получить подсказку, пока говорит epseak. Это сработало: 'fortune -a> a.txt && (espeak -f a.txt &) && cat a.txt | cowsay -W65 && rm a.txt' С твоей памятью я получал речь, но пустой пузырь пузырьков! Мне также нужно было переместить espeak в начало команды, потому что a.txt удалялся до того, как espeak смог его найти. – user2085548

2

Вы можете использовать tee в сочетании с заменой процесса.

fortune -a | tee >(cowsay -W65) >(espeak) 
+0

Прочитав 'man tee', я нашел, что это работает очень хорошо: ' fortune -a | tee> (cowsay -W65)> (espeak)> -' '' -' предотвращает копирование в STDOUT. Единственная оставшаяся проблема, с которой я сейчас сталкиваюсь, - это мое приглашение перед выпуском cowsay. Я пробовал '&& echo' - это разные места безрезультатно. – user2085548

+0

Да, я забыл подавить стандартную версию; обычно я использую '>/dev/null', но'> -' короче. Вывод приглашения объясняется асинхронным характером замещений процесса. Что-то больше похоже на 'mkfifo foo bar; фортуна -a | tee foo> bar; cowsay -W65 chepner

1

tee команды могут быть соединены друг с другом:

fortune | tee cowsay | tee espeak 
0

Спасибо всем за ваши полезные ответы!

Лучшее решение для моего случая использования я нашел до сих пор это:

fortune -a > a.txt && (espeak -f a.txt &) && cat a.txt |cowsay -W65 && rm a.txt 

, поскольку она представляет командную строку после текста и речи и выглядит самый хороший (выход-накрест). Это в моем .bashrc, поэтому я хочу, чтобы он выглядел хорошо, когда я запускаю оболочку терминала. Не сильно отличается от моей первоначальной попытки!

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

[email protected] ~ $ _________________________________________ 
/Be wary of strong drink. It can make \ 
| you shoot at tax collectors and miss. | 
|           | 
\ -- Lazarus Long, "Time Enough for Love"/
----------------------------------------- 
     \ ^__^ 
     \ (oo)\_______ 
      (__)\  )\/\ 
       ||----w | 
       ||  || 

Личное сообщение найдено в ответах. Правильно ли я это делаю?

1

Это мое решение. Сначала вы сохраняете результат удачи, чем печатаете cowsay с текстом, который вы сохранили до и в конце espeak.

clear;save=$(fortune);cowsay -f gnu <<< "$save"; espeak <<< "$save" 
0

Я использую Xclip

состояние | xclip; xclip -o | cowsay; xclip -o | espeak -ves &

xclip необходимо установить в первую очередь.

фортуна | xclip> прочитать текст из состояния.

xclip -o | cowsay -> отправить текст в cowsay.

xclip -o | speak -ves & -> отправьте текст на espeak и дайте подсказку.

Смежные вопросы