Действительно ли возможно добавить пробелы слева от каждого вывода к stdout (и stderr если возможный) когда я команды выполнения в сценарии оболочки удара?
Я хотел бы сделать что-то как:
#!/bin/bash
echo Installing: Something
echo " => installing prerequisite1"
## INSERT MAGICAL LEFT SPACES COMMAND HERE ##
apt-get install -q -y prerequisite
## ANOTHER MAGICAL CANCELLING LEFT SPACES COMMAND HERE ##
echo " => installing prerequisite2"
# ... the padding again ...
wget http://abc.com/lostzilla.tar.gz
tar vzxf lostzilla.tar.gz
cd lostzilla-1.01
./configure
make && make install
# ... end of padding ...
echo Done.
Какая-либо идея?
Править: Добавленные кавычки к команде эха, иначе они не будут дополнены.
Да, вы можете процитировать их для простых вещей:
echo ' => installing prerequisite1'
и направить вывод через sed
для сложных вещей:
tar vzxf lostzilla.tar.gz 2>&1 | sed 's/^/ /'
2> & 1
помещает stdout и stderr в поток stdout, а sed
заменяет каждый маркер начала строки тремя пробелами.
Я не уверен, насколько хорошо это будет работать с чем-то вроде wget
, которое выполняет всевозможные манипуляции с курсором.
Здесь показан пример:
pax> ls -1 p*
phase1.py
phase1.sh
phase2.py
phase2.sh
primes.c
primes.exe
primes.sh
primes.stat
pax> ls -1 p* | sed 's/^/ /'
phase1.py
phase1.sh
phase2.py
phase2.sh
primes.c
primes.exe
primes.sh
primes.stat
В прошлом я использовал один трюк, чтобы убедиться, что сценарии сами позаботятся об отступах:
#!/bin/bash
if [[ "${DONT_EVER_SET_THIS_VAR}" = "" ]] ; then
export DONT_EVER_SET_THIS_VAR=except_for_here
$0 | sed 's/^/ /'
exit
fi
ls -1 p*
Это повторно запустит сценарий с отступом через sed
, если это еще не сделано. Таким образом, вам не нужно беспокоиться об изменении всех ваших операторов вывода. Я знаю, что это что-то вроде хака, но я обычно делаю то, что необходимо для быстрых и грязных сценариев оболочки.
Если вы хотите включать и выключать интервалы, используйте следующий сценарий awk:
#!/usr/bin/gawk -f
/^#SPACEON/ { spaces=1; }
/^#SPACEOFF/ { spaces=0; }
!/^#SPACE/ {
if(spaces) {
print " " $0;
} else {
print $0;
}
}
Примечание что есть небольшие проблемы с вашим bash scipt. Примечательно, что использование =>
в ваших операторах эха выведет символ =
в файл «установка».
#!/bin/bash
echo Installing: Something
echo '=> installing prerequisite1'
echo '#SPACEON'
echo You would see apt-get install -q -y prerequisite
echo '#SPACEOFF'
echo '=> installing prerequisite2'
echo '#SPACEON'
echo You would see wget http://abc.com/lostzilla.tar.gz
echo You would see tar vzxf lostzilla.tar.gz
echo You would see cd lostzilla-1.01
echo You would see ./configure
echo You would see make \&\& make install
echo '#SPACEOFF'
echo Done.
Объединение этих двух вещей дает мне:
$ ./do-stuff | ./magic-spacing
Installing: Something
=> installing prerequisite1
You would see apt-get install -q -y prerequisite
=> installing prerequisite2
You would see wget http://abc.com/lostzilla.tar.gz
You would see tar vzxf lostzilla.tar.gz
You would see cd lostzilla-1.01
You would see ./configure
You would see make && make install
Done.
Где do-stuff - ваш сценарий bash, а magic-spacing - мой сценарий awk, приведенный выше.
В зависимости от того, как команда записывает в стандартный вывод, вы можете просто сделать отступ с помощью простого сценария awk:
$ echo -e 'hello\nworld' | awk '{print " ",$0}'
hello
world
Совсем без магии вы можете использовать printf, чтобы сделать следующее:
# space padding for single string
printf "%-4s%s\n" "" "=> installing prerequisite1"
# space padding for single command output
# use of subshell leaves original IFS intact
( IFS=$'\n'; printf " %s\n" $(command ls -ld * 2>&1) )
# note: output to stderr is unbuffered
( IFS=$'\n'; printf " %s\n" $(command ls -ld * 1>&2) )
Также можно группировать команды, заключая их в фигурные скобки и добавляя пробел к их выводу, как показано ниже:
{
cmd1 1>&2
cmd2 1>&2
cmd3 1>&2
} 2>&1 | sed 's/.*/ &/'
Можно перенаправить stdout в stderr скрипт / оболочку с помощью exec ...
(
exec 1>&2
command ls -ld *
) 2>&1 | sed 's/^/ /'