出力ファイルにコマンドを含めますか?


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>

3
他にも多くの優れた柔軟なソリューションが存在するため、コマンドを2回入力して手動でファイルに書き込むことを提案する回答を受け入れず、代わりに汎用ソリューションの1つを受け入れることを検討する必要があります。
バイトコマンダー

回答:


18

単純な関数を使用します。これを~/.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-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

ここでゴールポストを移動するつもりはありませんが、エイリアスを受け入れるようにコードを取得する方法はありますか?たとえば、にエイリアスapt-cache dependsを作成するとacd、を実行すると「コマンド 'acd'が見つかりませんでした、つまり:...」が表示されますruncom acd leafpad > out
モニカの正義

@DKBoseエイリアスは、シェルではなく.bashrcファイルで定義され、関数は$ PATH変数の下にあるバイナリファイルのみを呼び出します。しかし、あなたは簡単なトリックを行うことができます。たとえば 、実際にlsはにエイリアスさls --color=auto'れます。できることは(エイリアスに単一引用符または二重引用符がない限り)、これは次のとおり $ terdonsFunction $(alias ls | awk -F '=' '{$1="";print}'| tr "'" " ") です。
セルギーKolodyazhnyy

または、コマンドを変数に変換します。前に答えで示したように。MYCOMMAND="apt-cache depends"; terdonsFunction $MYCOMMAND leafpad > out.txt
セルギーコロディアズニー

@ Serg、GARCIN Davidの回答をご覧ください:askubuntu.com/a/688936/248158
モニカの正義

これは「明らかな」答えであり、引数のいずれかが実行され、蓄積される可能性のある副作用を持つコードを含まない限り、うまく機能します。これはエッジケースであるため、あまり頻繁には発生しません。
ジョー

11

できるよ:

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

echoHere文字列(<<<)の代わりに使用する同じこと:

echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt
  • tee STDOUTおよびファイルにも書き込みます file.txt

  • teeie のSTDOUTはコマンドを実行し、STDOUTをに追加apt-cache depends kde-window-managerするために供給されbashます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>

1
素晴らしい答えです!シンプルでポイントまで!私はそれを試してteeいましたが、私のものは失敗し続けました。よくやった!+1
テランス

@Sethファイル記述子で遊ぶことも考えましたが、teeすっきりしているようです:)
heemayl

11

最もミニマル-アプローチ#4および#3、両方とも関数に変換できます。#2私のお気に入り- awk。#1はscriptコマンドを使用します-非常に用途の広いツールで、一般的なコマンドラインの記録に役立ちます。どこでも、記録したいものに適用できます。

アプローチ#1:/usr/bin/scriptコマンドライン出力を記録する ためのコマンド(デフォルトではubuntuに付属)があり、プロンプトとコマンドとともにすべてをキャプチャします。1つのコマンドとその出力を特定のファイルに保存するには、-cflagを使用して出力ファイルを指定します。例

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 20151022 星期四 085846
gnome-terminal
  Depends: gconf-service
    gconf-service:i386
  Depends: libatk1.0-0
  Depends: libc6
  Depends: libgconf-2-4
  (extra output omitted)

Script done on 20151022 星期四 085846

アプローチ#2:awk hackery

Awkにはスクリプトまたはsystem()コマンドからawkシェルコマンドを実行できる機能があります。出力は、画面に表示され、最初にコマンドが表示され、次に出力されます。表示されているものをファイルにリダイレクトするには、>演算子を使用します。

これは2つの方法で実行できます-ユーザーに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に仕事を依頼してください

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:(2番目のお気に入り)

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(別名<<< "string")に引数を提供しsh -cxargs

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 {}; {}"'

素晴らしいですが、Arronicalのコードが行うようなコマンドは含まれていません。
モニカの正義

@DKBoseコマンドを含む別のアプローチを追加します。5分
セルギーコロディアズニー

@DKBose私のアプローチ#2はどうですか?
セルギーKolodyazhnyy

それawkは賢いです、本当に非常に設定可能な小さなファラではありません!`スクリプトは他のいくつかの用途にも便利です。
アーロニカル

1
スクリプトを使用すると、エコーなどで表示されたときにコードを実行する可能性のある引数による副作用を回避できるため、これが最善の答えです。2回目の意図した実行により、コマンドを個別に実行した場合と異なる結果が得られる可能性があります
ジョー

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>

5

エイリアス展開(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

4

もっと簡単な方法があるかもしれませんが、スクリプトでそれを行うことができます。

#!/bin/sh
echo $1
apt-cache depends $1

scriptホームフォルダーにこのコンテンツを含むファイルを作成し、実行権限を付与します

chmod +x script

この方法で実行します:

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

このアプローチには、必要に応じてコマンドラインを後で簡単に繰り返すことができるという利点があります。リダイレクトをスクリプトに書き込むこともできます。これscript.shにより、常にscript.logその出力で呼び出されるファイルが作成されます。
ガウラフ

4

1行のBash関数を使用した非常にシンプルなソリューション

準備:

このアプローチでは、カスタムbash関数を使用して、必要な機能を提供します。端末セッションで次の行を実行して定義します。次の代わりに任意の有効なbash変数名を選択できることに注意してくださいrunandlog

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

ただし、これは現在のBashセッションでのみ持続します。つまり、ターミナルウィンドウを閉じた後、関数は削除されます。
ただし、試してみて気に入った場合は、~/.bashrcファイルを編集し、この行をファイルの最後に追加することで、いつでも利用できるようにすることができます。

使い方:

関数を定義したら、それを使用してコマンドを実行し、コマンド自体とその出力の両方をファイルに記録できます。すでに関数に含めた、または実行した正確な時間など、それを実行したユーザーなどの情報を追加することもできます。コメントでの機能リクエストは大歓迎です!:)

構文は簡単です:

runandlog LOGFILENAME YOUR-COMMAND-WITH-ARGUMENTS

例:

bytecommanderホームディレクトリから操作するuserとしてのセッションの例は次のようになります。

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

3

かなり巧妙ではないが機能的なトリックは次のとおりです。

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

glyいですが、動作します!


ソリューションがより広く適用できるので、私はこの答えを受け入れます。
モニカの正義

@DKBoseモジュールを2回入力する必要があります。しかし、スクリプトを使用したソリューションは本当に普遍的です。
Pilot6

残念ながら、私が要求したことを実行しても、この答えを受け入れないでください。気にしないでください!
モニカの正義

2
@DKBoseの問題ではありませんが、回答を提出したとき、それはかなりエレガントなソリューションであることがわかりました。
アーノニカル

2

コマンドを最初に印刷し、その後コマンドの出力を出力する関数にコマンドを渡すことができます(リダイレクトは意図的に印刷されたコマンドから除外されます。コマンドから引用符を削除し、$@代わりに印刷して実行することで簡単に変更できます$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
  • <<<"[...]":here string; [...]リダイレクトされるcatstdin
  • $(<foo):コマンド置換; 「foo」のコンテンツに置き換えられます。
  • cat [...] - >foo:「foo」に連結stdin[...]て出力します。
  • <([...]):プロセス置換:の出力を含むファイル記述子に置き換えられます[...]
  • history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p':最後の2つのコマンドを出力し、最初の行から2つのスペースとそれに続く1つ以上の数字と2つのスペースを削除して出力します。
$ 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

なぜ印刷するだけ$1ですか?必要はありませんeval
テルドン

@terdonまあ、アイデアは、印刷されたコマンドからリダイレクトを除外することでした。これは、OPの場合はもっと見栄えが良いと思ったからです。それにもかかわらず、私が今それを変更するならば、それはあなたの答えと同一です。しかし、はい、eval必要ではありません。なぜ以前に追加したのかわかりません。ありがとう。
コス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.