在输出文件中包含命令?

对不起,令人困惑的标题!

假设我跑了

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:  

而不是像这样:

 kde-window-manager Depends: kde-runtime Depends: libc6 |Depends: libegl1-mesa Depends:  

我只想使用一个简单的function。 将其添加到~/.bashrc文件中:

 function runcom(){ echo "$@" ## Run the command $@ } 

现在,只要您想运行命令并打印它,您就可以:

 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-mesa Depends: libgcc1 |Depends: libgl1-mesa-glx Depends:  libgl1-mesa-swx11 libgl1-mesa-glx |Depends: libgles2-mesa Depends:  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-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:  Breaks:  Breaks: kde-workspace-data Breaks:  Breaks: kdeartwork-theme-window Breaks: kdeartwork-theme-window:i386 Breaks:  Breaks:  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:  Replaces:  Replaces:  Conflicts: kde-window-manager:i386 

你可以做:

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

使用echo代替Here strings( <<< ):

 echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt 
  • tee将写入STDOUT以及文件file.txt

  • teeapt-cache depends kde-window-manager的STDOUT 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:  

大多数简约 – 方法#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 hackery

awk具有system()函数,允许您awk脚本或命令运行shell命令。 输出将显示在屏幕上,先命令,然后输出。 要将您看到的内容重定向到文件,请使用>运算符。

这可以通过两种方式完成 – 要求用户从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) }'

  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

方法#4 :(我的第二个最爱)

灵感来自ByteCommander的post; 我们可以使用read然后在子shell中运行必要的命令

 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:

使用echohere string (又名<<< "string" )通过xargssh -c提供参数

 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 {}; {}"' 
  1. 启动script -q outputfile
  2. 执行你的命令
  3. CtrlD.
  4. 打开文件输出文件

启动script

 [aboettger:~/tmp] % script -q ~/Desktop/kwin-depends 

开始你的命令

 [aboettger:~/tmp] % apt-cache depends kde-window-manager  [aboettger:~/tmp] % 

CtrlD.

 Script done, file is /home/aboettger/Desktop/kwin-depends 

显示您的命令和输出

 [aboettger:~/tmp] % cat ~/Desktop/kwin-depends 

你会看到这样的东西

 [aboettger:~/tmp] % apt-cache depends 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 

在Home文件夹中创建包含此内容的文件script ,并授予执行权限

 chmod +x script 

以这种方式运行:

 ./script kde-window-manager > ~/Desktop/kwin-depends 

使用单行Bashfunction的极其简单的解决方案

制备:

此方法使用自定义bash函数来提供所需的function。 您可以通过在终端会话中执行以下行来定义它。 请注意,您可以选择任何有效的bash变量名称而不是runandlog

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

然而,这仅对当前的Bash会话持续存在,这意味着在关闭终端窗口之后,该function将消失。
如果您尝试并喜欢它,您可以通过编辑~/.bashrc文件并将此行追加到它的末尾来使其始终可用。

如何使用:

定义了该函数后,您可以使用它来运行命令,同时将命令本身及其输出记录到文件中。 您甚至可以添加更多信息,例如执行它的用户,我已经包含在函数中的信息,或者运行的确切时间。 欢迎评论中的function请求! 🙂

语法很简单:

 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 

一个相当不巧妙但function性的技巧是:

 (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 
  • <<<"[...]" :这里的字符串; [...]被重定向到catstdin ;
  • $( :命令替换; 它被“foo”的内容所取代;
  • cat [...] - >foo :将stdin连接到[...]并输出到“foo”;
  • <([...]) :进程替换:用包含[...]输出的文件描述符替换;
  • history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p' history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p' :输出最后两个命令,删除两个空格后跟一个或多个数字后跟两个第一行的空格并打印出来;
 $ printf "bar\n" >foo $ <<<"$(foo $ cat foo printf "bar" >foo bar