LINUX.ORG.RU

Выполнить баш-скрипт, сохранить выполняемую команду, stdout и stderr в один файл

 


0

2

Привет.

Допустим, есть bash-скрипт 1.sh:

sleep 10s
echo AAA
rm -rf /tmp/1/*
rm -rf /tmp/2/*
ls /tmp/

Мне нужно запустить его, и сохранить stdout\stderr в файл и чтобы было понятно, какая команда записала выполнялась перед этим.

Перенаправить syderr\stdout я могу, например, так:

./1.sh &>/tmp/1.log

Но я не узнаю, какая команда именно записала то или иное в лог.

Хочу получить типа этого:

sleep 10s
тут stderr+stdout
echo AAA
тут stderr+stdout 
...

Как это сделать? На ум приходит только тупой цикл типа этого:

commands="sleep 10s
echo AAA
rm -rf /tmp/1/*
rm -rf /tmp/2/*
ls /tmp/"

for i in $commands
do
echo $i
$i
done

Как лучше сделать?

★★★

Последнее исправление: iljuase (всего исправлений: 2)
echo "CMD: sleep 10s"
sleep 10s
echo "CMD: echo AAA"
echo AAA
echo "CMD: rm -rf /tmp/1/*"
rm -rf /tmp/1/*
echo "CMD: rm -rf /tmp/2/*"
rm -rf /tmp/2/*
echo "CMD: ls /tmp/"
ls /tmp/

Пожалуйста, так вам будет будет понятно какая команда выполнялась перед.

infomeh ★★
()
Ответ на: комментарий от Yorween

Лорчую. Или если менять скрипт нельзя, то можно так

set -x
source 1.sh
legolegs ★★★★★
()

У вас скрипт простой? С простыми командами как в примере? Тогда можно его читать построчно и выполнять через eval. Это даст возможность раздельно записать имена выполняемых команд как в stdout, так и в stderr, да хоть ещё и в лог.

Для возбудившихся по ключевому слову eval и прочих rm -rf, чтобы два раза не вставать, сразу объясняю: тут это по делу, ничего не меняет и даже лучше - можно ручками как раз проверить.

vodz ★★★★★
()

exec >file.txt 2>&1
set -v
...

teod0r ★★★★★
()
Ответ на: комментарий от Borifed

Это отсылка на то, что в этой директории может быть файлы с названием " --no-preserve-root /" или что-то в таком духе (можно напихать в название опций по вкусу). Без — и кавычек это имя будет воспринято как дополнительные опции для rm. Если просто — есть, то хотя бы просто ругнется на то, что нет файла с именем "--no-preserve-root".

lu4nik ★★★
()
Ответ на: комментарий от lu4nik

Без — и кавычек это имя будет воспринято как дополнительные опции для rm. Если просто — есть, то хотя бы просто ругнется

Получается, лучше всего использовать двойные кавычки?

Borifed
()
Ответ на: комментарий от lu4nik

Ох как я люблю шелл за вот это всё.

anonymous
()
Ответ на: комментарий от lu4nik

Это отсылка на то, что в этой директории может быть файлы с названием " --no-preserve-root /" или что-то в таком духе

Чушь какая. Во-первых, в каталоге не может быть имени с '/'. Во-вторых, вы какую-то рекурсию тут изображаете. Оно так не работает. Чтобы оно взяло имя и снова распарсило там пробелы, надо через eval пропускать. Скорее всего из такого примера вы это и подчерпнули, не разбираясь о чём это.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от Borifed

Получается, лучше всего использовать двойные кавычки?

Нет, не получается. Звездочки rm сам не парсит. См. выше.

vodz ★★★★★
()
Ответ на: комментарий от lu4nik

Разве не сначала глобы обрабатываются, а потом идет разделение на аргументы?

Нет, конечно. Это же было чудовищно неудобно, когда не известно сколько и какие будут аргументы. Самое удивительное, что проверить то пять секунд:

$ mkdir d
$ touch "d/ a b "
$ ls d/*
d/ a b

Как видите, никаких «a»: файл не найден...

vodz ★★★★★
()
Ответ на: комментарий от vodz

Действительно, я обосрался, можно было не ёрничать.

lu4nik ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.