Включить команду в выходной файл?

17

Извините за запутанное название!

Предположим, что я запустил

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>
    
задан DK Bose 22.10.2015 в 14:18
источник

9 ответов

19

Я бы просто использовал простую функцию. Добавьте это в свой файл ~/.bashrc :

function runcom(){
    echo "[email protected]"
    ## Run the command
    [email protected]
}

Теперь, когда вы хотите запустить команду и распечатать ее, вы можете сделать:

runcom apt-cache depends kde-window-manager > out

Вышеприведенный файл:

$ cat out
apt-cache depends kde-window-manager
kde-window-manager
  Depends: perl
  Depends: kde-runtime
  Depends: kde-style-oxygen
  Depends: libc6
 |Depends: libegl1-mesa
  Depends: <libegl1-x11>
    libegl1-mesa
  Depends: libgcc1
 |Depends: libgl1-mesa-glx
  Depends: <libgl1>
    libgl1-mesa-swx11
    libgl1-mesa-glx
 |Depends: libgles2-mesa
  Depends: <libgles2>
    libgles2-mesa
  Depends: libice6
  Depends: libkactivities6
  Depends: libkcmutils4
  Depends: libkdeclarative5
  Depends: libkdecorations4abi2
  Depends: libkdecore5
  Depends: libkdeui5
  Depends: libkio5
  Depends: libknewstuff3-4
  Depends: libkwineffects1abi5
  Depends: libkwinglesutils1
  Depends: libkwinglutils1abi2
  Depends: libkworkspace4abi2
  Depends: libplasma3
  Depends: libqt4-dbus
  Depends: libqt4-declarative
  Depends: libqt4-script
  Depends: libqtcore4
  Depends: libqtgui4
  Depends: libsm6
  Depends: libstdc++6
  Depends: libwayland-client0
 |Depends: libwayland-egl1-mesa
  Depends: <libwayland-egl1>
    libwayland-egl1-mesa
  Depends: libx11-6
  Depends: libx11-xcb1
  Depends: libxcb-composite0
  Depends: libxcb-damage0
  Depends: libxcb-image0
  Depends: libxcb-keysyms1
  Depends: libxcb-randr0
  Depends: libxcb-render0
  Depends: libxcb-shape0
  Depends: libxcb-shm0
  Depends: libxcb-sync1
  Depends: libxcb-xfixes0
  Depends: libxcb-xtest0
  Depends: libxcb1
  Depends: libxcursor1
  Depends: libxext6
  Depends: libxrandr2
  Depends: libxxf86vm1
  Breaks: kde-style-bespin
  Breaks: kde-style-bespin:i386
  Breaks: <kde-style-skulpture>
  Breaks: <kde-style-skulpture:i386>
  Breaks: kde-workspace-data
  Breaks: <kde-workspace-data:i386>
  Breaks: kdeartwork-theme-window
  Breaks: kdeartwork-theme-window:i386
  Breaks: <kdebase-workspace-data>
  Breaks: <kdebase-workspace-data:i386>
  Breaks: kwin-style-crystal
  Breaks: kwin-style-crystal:i386
  Breaks: kwin-style-dekorator
  Breaks: kwin-style-dekorator:i386
  Breaks: kwin-style-qtcurve
  Breaks: kwin-style-qtcurve:i386
  Replaces: kde-workspace-data
  Replaces: <kde-workspace-data:i386>
  Replaces: <kdebase-workspace-data>
  Replaces: <kdebase-workspace-data:i386>
  Conflicts: kde-window-manager:i386
    
ответ дан terdon 23.10.2015 в 11:28
источник
12

Вы можете сделать:

tee file.txt <<<'apt-cache depends kde-window-manager' | bash >>file.txt

То же самое, используя echo вместо Here string ( <<< ):

echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt
  • tee будет записывать в STDOUT, а также в файл file.txt

  • STDOUT tee i.e. 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>
    
ответ дан heemayl 22.10.2015 в 18:28
11

Большинство минималистических - подход № 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秒

Подход № 2: хакерство awk

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) версия командной строки командной строки; не включая выход, чтобы избежать слишком долгого ответа. Снова добавьте > для перенаправления на файл

awk 'BEGIN{for (i=1; i<= ARGC; i++) myString = myString"  "ARGV[i]; print myString; system(myString)  }' apt-cache depends gnome-terminal

Подход №3: попросите bash выполнить работу за вас

[email protected]:~$ 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

Подход №4: (мой второй любимый)

Вдохновленный постом 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 through 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

И если вы хотите, вы можете использовать этот же трюк с псевдонимом:

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 {}; {}"'
    
ответ дан Sergiy Kolodyazhnyy 22.10.2015 в 14:59
6
  1. Начать script -q outputfile
  2. Выполните команду
  3. Нажмите Ctrl - D
  4. Откройте файл outputfile

Пример

Начать 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>
    
ответ дан A.B. 23.10.2015 в 11:29
5

Если вы хотите расширение псевдонима (только bash), вы можете сделать это следующим образом:

function runcmd
{
    local check_cmd=${BASH_ALIASES[]}

    if [ -z "$check_cmd" ]; then
        check_cmd=
    fi

    shift #skip 1st arg

    echo "$check_cmd [email protected]"
    $check_cmd [email protected]
}

Теперь вы можете запустить

runcmd acd leafpad > out
    
ответ дан GARCIN David 23.10.2015 в 15:16
4

Может быть, проще, но вы можете сделать это по сценарию:

#!/bin/sh
echo 
apt-cache depends 

Создайте файл script с этим контентом в вашей домашней папке и дайте разрешение на выполнение

chmod +x script

Запустите его так:

./script kde-window-manager > ~/Desktop/kwin-depends
    
ответ дан Pilot6 22.10.2015 в 14:35
4

Чрезвычайно простое решение с использованием однострочной функции Bash

Способ приготовления:

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

runandlog () ( IFS=' '; printf "[%s] $ %s\n%s\n" "$USER" "${*:2}" "$("${@:2}")" | tee -a "" | tail -n +2; )

Это, однако, сохраняется только для текущей сессии Bash, что означает, что после закрытия окна терминала функция не будет. Если вы попробовали и понравились, вы можете сделать это всегда доступным, отредактировав файл ~/.bashrc и добавив эту строку в конец.

Как использовать:

После определения функции вы можете использовать ее для запуска команд при регистрации самой команды и ее вывода в файл. Вы могли бы даже добавить дополнительную информацию, такую ​​как пользователь, который ее выполнил, который я уже включил в эту функцию, или точное время ее выполнения. Запросы функций в комментариях приветствуются! :)

Синтаксис прост:

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
    
ответ дан Byte Commander 22.10.2015 в 19:05
3

Довольно нескромный, но функциональный трюк:

(echo "apt-cache depends kde-window-manager" && apt-cache depends kde-window-manager) > ~/Desktop/kwin-depends

Уродливый, но он работает!

    
ответ дан Arronical 22.10.2015 в 14:35
2

Вы можете просто передать команду функции, которая сначала выведет команду и выдает команду (перенаправления из печатной команды намеренно, вы можете легко изменить это, удалив кавычки из команды и распечатав и работает [email protected] вместо в функции):

function myfunction() {
    printf "%s\n\n" ""
    
}
$ myfunction "printf \"bar\n\"" > foo
$ cat foo
printf "bar\n"

bar

Чтобы добавить команду, вы можете запустить эту команду, которая будет вставлять последний запуск команды в верхней части файла:

<<<"$(<foo)" cat <(history 2 | sed -n '1s/  [0-9][0-9]*  \(.*\)/\n/p') - >foo
  • <<<"[...]" : здесь строка; [...] перенаправляется на cat stdin ;
  • $(<foo) : замена команды; он заменяется содержимым «foo»;
  • cat [...] - >foo : объединяет stdin в [...] и выводит на "foo";
  • <([...]) : замена процесса: он заменяется файловым дескриптором, содержащим выход [...] ;
  • history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\n/p' : выводит последние две команды, удаляет два пробела, за которыми следуют одна или несколько цифр, за которыми следуют два пробела из первой строки и печатает их;
$ printf "bar\n" >foo
$ <<<"$(<foo)" cat <(history 2 | sed -n '1s/  [0-9][0-9]*  \(.*\)/\n/p') - >foo
$ cat foo
printf "bar" >foo

bar
    
ответ дан kos 22.10.2015 в 15:59