Извините за запутанное название!
Предположим, что я запустил
apt-cache depends kde-window-manager > ~/Desktop/kwin-depends
Я получаю файл с именем «kwin-depends» в папке «Мой рабочий стол».
Есть ли какая-то трюк, чтобы включить команду, которую я выпустил как часть файла, желательно в начале файла?
Итак, по крайней мере, в 14.04 LTS первые несколько строк будут выглядеть так: :
apt-cache depends kde-window-manager > ~/Desktop/kwin-depends
kde-window-manager
Depends: kde-runtime
Depends: libc6
|Depends: libegl1-mesa
Depends: <libegl1-x11>
Вместо этого:
kde-window-manager
Depends: kde-runtime
Depends: libc6
|Depends: libegl1-mesa
Depends: <libegl1-x11>
Вы можете сделать:
tee file.txt <<<'apt-cache depends kde-window-manager' | bash >>file.txt
То же самое, используя echo вместо Здесь строки (<<<):
echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt
tee будет записывать в STDOUT а также к файлу file.txt STDOUT для tee, т.е. apt-cache depends kde-window-manager, будет передан на bash, чтобы запустить команду и добавить STDOUT к file.txt. Пример:
$ echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt
$ cat file.txt
apt-cache depends kde-window-manager
kde-window-manager
Depends: kde-runtime
Depends: libc6
|Depends: libegl1-mesa
Depends: <libegl1-x11>
Большинство минималистичных - подход № 4 и № 3, оба могут быть преобразованы в функцию; # 2 мой любимый - awk. # 1 использует команду script - очень универсальный инструмент, полезный для записи командной строки в целом; применимо в любом месте, независимо от того, что вы хотите записать.
Подход №1: есть команда /usr/bin/script (которая по умолчанию работает с ubuntu) для записи вывода командной строки, который захватывает все, вместе с подсказка и команда. Чтобы просто сохранить одну команду и ее вывод в конкретный файл, используйте флаг -c и укажите выходной файл. Пример
xieerqi:$ script -c 'apt-cache depends gnome-terminal' outputFile.txt
Script started, file is outputFile.txt
gnome-terminal
Depends: gconf-service
gconf-service:i386
Depends: libatk1.0-0
Depends: libc6
Depends: libgconf-2-4
Depends: libgdk-pixbuf2.0-0
(extra output omitted)
Script done, file is outputFile.txt
xieerqi:$ cat outputFile.txt
Script started on 2015年10月22日 星期四 08时58分46秒
gnome-terminal
Depends: gconf-service
gconf-service:i386
Depends: libatk1.0-0
Depends: libc6
Depends: libgconf-2-4
(extra output omitted)
Script done on 2015年10月22日 星期四 08时58分46秒
Подход №1:
Awk имеет функцию system(), которая позволяет запускать команды оболочки из скрипта или команды awk. Вывод будет отображаться на экране, сначала команду, затем вывод. Для перенаправления того, что вы видите в файле, используйте оператор >.
Это можно сделать двумя способами: попросите пользователя ввести материал из stdin или в качестве аргумента командной строки. [1] awk 'BEGIN{ print "Enter command to run: "; getline com < "/dev/stdin"; system(com) }'
awk 'BEGIN{ print "Enter command to run: "; getline com < "/dev/stdin"; system(com) }'
Enter command to run:
apt-cache depends gnome-terminal
gnome-terminal
Depends: gconf-service
gconf-service:i386
Depends: libatk1.0-0
Depends: libc6
Depends: libgconf-2-4
Depends: libgdk-pixbuf2.0-0
Depends: libglib2.0-0
(extra output omitted)
(2) Версия командной строки args; не включая выход, чтобы избежать слишком долгого ответа. Снова добавьте > для перенаправления на файл
awk 'BEGIN{for (i=1; i<= ARGC; i++) myString = myString" "ARGV[i]; print myString; system(myString) }' apt-cache depends gnome-terminal
Подход №3: попросите bash выполнить задание для вас
xieerqi@eagle:~$ bash -c ' MYCOMMAND="apt-cache depends gnome-terminal"; echo $MYCOMMAND ; $MYCOMMAND '
apt-cache depends gnome-terminal
gnome-terminal
Depends: gconf-service
gconf-service:i386
Depends: libatk1.0-0
Depends: libc6
Depends: libgconf-2-4
Depends: libgdk-pixbuf2.0-0
Depends: libglib2.0-0
Перенаправить в файл с помощью оператора > :
bash -c ' MYCOMMAND="apt-cache depends gnome-terminal"; echo $MYCOMMAND ; $MYCOMMAND ' > output.txt
Подход №3: попросите bash выполнить задание для вас
Вдохновленный постом ByteCommander; мы можем использовать read, а затем выполнить необходимые команды в подоболочке
read command && (printf "COMMAND: %s" "$command";printf "\n+++++++\n"; sh -c "$command")
Пример прогона:
xieerqi:$ read command && (printf "COMMAND READ: %s" "$command";printf "\n+++++++\nOUTPUT\n"; sh -c "$command")
printf "This was a triumph; I'm making a note here - huge success"
COMMAND READ: printf "This was a triumph; I'm making a note here - huge success"
+++++++
OUTPUT
This was a triumph; I'm making a note here - huge success
Подход # 5:
Использовать echo или here string (aka <<< "string") для предоставления аргументов sh -c через xargs
xieerqi:$ echo "apt-cache policy gnome-terminal" | xargs -I {} bash -c 'echo {}; {}'
apt-cache policy gnome-terminal
gnome-terminal:
Installed: 3.6.2-0ubuntu1
Candidate: 3.6.2-0ubuntu1
Version table:
*** 3.6.2-0ubuntu1 0
500 http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
100 /var/lib/dpkg/status
И если вы хотите, вы можете использовать этот же трюк с псевдонимом: [!d21 ]
xieerqi:$ printAndRun <<< "apt-cache policy gnome-terminal"
apt-cache policy gnome-terminal
gnome-terminal:
Installed: 3.6.2-0ubuntu1
Candidate: 3.6.2-0ubuntu1
Version table:
*** 3.6.2-0ubuntu1 0
500 http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
100 /var/lib/dpkg/status
xieerqi:$ type printAndRun
printAndRun is an alias for 'xargs -I {} bash -c "echo {}; {}"'
Пример
Начать script
[aboettger:~/tmp] % script -q ~/Desktop/kwin-depends
Начните свою команду
[aboettger:~/tmp] % apt-cache depends kde-window-manager
<kde-window-manager>
[aboettger:~/tmp] %
Нажмите Ctrl-D
Script done, file is /home/aboettger/Desktop/kwin-depends
Покажите свою команду и выведите
[aboettger:~/tmp] % cat ~/Desktop/kwin-depends
, а вы увидит что-то подобное
[aboettger:~/tmp] % apt-cache depends kde-window-manager
<kde-window-manager>
Если вы хотите расширение псевдонима (только bash), вы можете сделать это следующим образом:
function runcmd
{
local check_cmd=${BASH_ALIASES[$1]}
if [ -z "$check_cmd" ]; then
check_cmd=$1
fi
shift #skip 1st arg
echo "$check_cmd $@"
$check_cmd $@
}
Теперь вы можете запустить
runcmd acd leafpad > out
Может быть проще, но вы можете сделать это по сценарию:
#!/bin/sh
echo $1
apt-cache depends $1
Создайте файл script с этим контентом в вашей домашней папке и дайте разрешение на выполнение
chmod +x script
Запустите его следующим образом:
./script kde-window-manager > ~/Desktop/kwin-depends
В этом подходе используется пользовательская функция bash для обеспечения желаемой функциональности. Вы определяете его, выполняя следующую строку в сеансе терминала. обратите внимание, что вы можете выбрать любое действительное имя переменной bash вместо runandlog:
runandlog () ( IFS=' '; printf "[%s] $ %s\n%s\n" "$USER" "${*:2}" "$("${@:2}")" | tee -a "$1" | tail -n +2; )
Это, однако, сохраняется только для текущего сеанса Bash, что означает, что после закрытия окна терминала функция исчезнет. Если вы попробовали и понравились, вы можете сделать это всегда доступным, отредактировав файл ~/.bashrc и добавив эту строку в конец.
After определив эту функцию, вы можете использовать ее для запуска команд при регистрации самой команды и ее вывода в файл. Вы могли бы даже добавить дополнительную информацию, такую как пользователь, который ее выполнил, который я уже включил в эту функцию, или точное время ее выполнения. Запросы функций в комментариях приветствуются! :)
Синтаксис прост:
runandlog LOGFILENAME YOUR-COMMAND-WITH-ARGUMENTS
Пример сеанса как пользователь bytecommander, работающий из домашнего каталога, может выглядеть так: это:
bytecommander: ~ $ runandlog mylogfile fortune
A mathematician is a device for turning coffee into theorems.
-- P. Erdos
Что приведет к созданию нового файла mylogfile (если он уже существует, функция добавит к нему вывод!) в текущем каталоге с содержимым:
[bytecommander] $ fortune
A mathematician is a device for turning coffee into theorems.
-- P. Erdos
Довольно нескромный, но функциональный трюк был бы:
(echo "apt-cache depends kde-window-manager" && apt-cache depends kde-window-manager) > ~/Desktop/kwin-depends
Уродливый, но он работает!
Вы можете просто передать команду функции, которая сначала выведет команду, а затем выдает команду (перенаправления не будут напечатаны из печатной команды намеренно, вы можете легко изменить это, удалив кавычки из команды и распечатав и $@ вместо $1 в функции):
function myfunction() {
printf "%s\n\n" "$1"
$1
}
$ myfunction "printf \"bar\n\"" > foo
$ cat foo
printf "bar\n"
bar
Чтобы добавить команду после этого, вы можете запустить эту команду, которая будет вставлять последний запуск команды в верхней части файл:
<<<"$(<foo)" cat <(history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p') - >foo
<<<"[...]": здесь строка; [...] перенаправляется на cat 's stdin; $(<foo): замена команды; он заменяется содержимым «foo»; cat [...] - >foo: объединяет stdin с [...] и выводит на «foo»; <([...]): замена процесса: он заменяется файловым дескриптором, содержащим вывод [...]; history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p': выводит последние две команды, удаляет два пробела, за которыми следует одна или несколько цифр, за которыми следуют два пробела из первой строки и печатает их; $ printf "bar\n" >foo
$ <<<"$(<foo)" cat <(history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p') - >foo
$ cat foo
printf "bar" >foo
bar