Некоторые тонкости стыковки ruby и bash
Введение
Последнее время больше занимаюсь работой системного администратора нежели программиста. Прошлую неделю даже пропустил написание статьи. Это, конечно, не означает, что совсем нечего рассказать.
Поскольку для быстроты я обычно пишу большинство скриптов на руби, необходимо чтобы они следовали некоторым тонкостям работы с командной строкой.
Условное выполнение
В bash кроме разделителей команд «&» и «;», существует ещё и условное выполнение списка команд с помощью «&&» и «||». Их работа зависит от кода, с которым произошёл выход.
exit0:
#!/usr/bin/env ruby
puts "Выход с кодом 0"
exit 0exit1:
#!/usr/bin/env ruby
puts "Выход с кодом 1"
exit 1Теперь если запустить скрипты в следующем сочетании:
./exit0 && ./exit0 && ./exit1 && ./exit0То вывод будет следующий:
Выход с кодом 0
Выход с кодом 0
Выход с кодом 1А если запустить скрипты в следующем сочетании:
./exit1 || ./exit1 || ./exit0 || ./exit1То вывод будет следующий:
Выход с кодом 1
Выход с кодом 1
Выход с кодом 0То есть, «&&» выполняет следующую команду, если предыдущая вышла с кодом 0, а «||» выполняет следующую команду, если предыдущая вернула ненулевой код. Условно говоря, первый список выполняется пока всё срабатывает, а второй пока не срабатывает.
Перенаправление вывода с помощью pipeline
Тут всё просто. Если в bash команды разделены с помощью «|», то вывод первой команды будет перенаправлен на вход второй.
Простая демонстрация из трёх файлов.
show:
#!/usr/bin/env ruby
$KCODE = "utf8"
$stdout.puts "stdin содержит: #{$stdin.read.inspect}"out:
#!/usr/bin/env ruby
$stdout.puts "Привет из stdout!"err:
#!/usr/bin/env ruby
$stderr.puts "[*stderr*] Привет из stderr!"
$stdout.puts "Привет из stdout!"Думаю, не составит труда выяснить, что выводят запущенные отдельно out и err, но вот, что из этого можно сделать с помощью pipeline:
./out | ./showвыводит
stdin содержит: "Привет из stdout!\n"Когда же есть обращение к другому каналу вывода, то
./err | ./showвыводит
[*stderr*] Привет из stderr!
stdin содержит: "Привет из stdout!\n"Вывод stderr можно перенаправить в stdout:
./err 2>&1 | ./showвыводит
stdin содержит: "[*stderr*] Привет из stderr!\nПривет из stdout!\n"