Komut çıktı dosyasına dahil edilsin mi?


17

Kafa karıştırıcı başlık için özür dilerim!

Farzedelim ki koşuyorum

apt-cache depends kde-window-manager > ~/Desktop/kwin-depends

Masaüstü klasörümde "kwin-depends" adlı bir dosya alacağım.

Dosyanın bir parçası olarak, tercihen dosyanın başlangıcında verdiğim komutu eklemenin bir yolu var mı?

Yani, en azından 14.04 LTS'de, ilk birkaç satır şöyle görünecektir:

apt-cache depends kde-window-manager > ~/Desktop/kwin-depends

kde-window-manager
  Depends: kde-runtime
  Depends: libc6
 |Depends: libegl1-mesa
  Depends: <libegl1-x11>

Bunun gibi:

kde-window-manager
  Depends: kde-runtime
  Depends: libc6
 |Depends: libegl1-mesa
  Depends: <libegl1-x11>

3
Şimdi başka birçok iyi ve esnek çözüm olduğu için, komutu iki kez yazarak dosyaya manuel olarak yazmayı ve bunun yerine çok yönlü çözümlerden birini kabul etmeyi öneren yanıtı kabul etmemelisiniz.
Bayt Komutanı

Yanıtlar:


18

Sadece basit bir fonksiyon kullanırdım. Bunu ~/.bashrcdosyanıza ekleyin :

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

Şimdi, bir komutu çalıştırmak ve yazdırmak istediğinizde şunları yapabilirsiniz:

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

Yukarıdakiler bu dosyayı üretir:

$ 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

Kale direklerini buraya taşımak istemiyorum ama kodunuzu takma adları da kabul etmenin bir yolu var mı? Örneğin, takma eğer apt-cache dependshiç acdben çalıştırdığınızda: Ben olsun "... Hayır komut 'acd' bunu mu demek istediniz, buldum" runcom acd leafpad > out.
DK Bose

@DKBose diğer adları kabukta değil .bashrc dosyasında tanımlanır ve işlevler yalnızca $ PATH değişkeni altında bulunan ikili dosyaları çağırır. Ama basit bir numara yapabilirsiniz. Örneğin, lsgerçekte takma addır ls --color=auto' . Ne (uzun sizin takma hiçbir tek tırnak veya çift tırnak olmadığı için gibi) yapabilirdi, şudur: $ terdonsFunction $(alias ls | awk -F '=' '{$1="";print}'| tr "'" " ") .
Sergiy Kolodyazhnyy

VEYA komutunuzu bir değişkene dönüştürün. Daha önce cevabımda gösterdiğim gibi. MYCOMMAND="apt-cache depends"; terdonsFunction $MYCOMMAND leafpad > out.txt
Sergiy Kolodyazhnyy

@Serg, lütfen GARCIN David'in cevabına bakınız: askubuntu.com/a/688936/248158
DK Bose

Bu "açık" cevaptır ve argümanlardan herhangi biri, yürüten ve birikebilecek yan etkileri olan kod içermediği sürece harika çalışır. Bu bir uç durum, bu yüzden çok sık gerçekleşmez.
Joe

11

Yapabilirsin:

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

echoHere dizeleri ( <<<) yerine aynı şey kullanılır :

echo 'apt-cache depends kde-window-manager' | tee file.txt | bash >>file.txt
  • tee STDOUT'a ve ayrıca dosyaya yazacak file.txt

  • teeYani STDOUT komutu çalıştırmak ve STDOUT öğesini eklemek için apt-cache depends kde-window-managerbeslenecektir .bashfile.txt

Misal:

$ 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
Mükemmel cevap! Basit ve noktaya! Ben ile bir çalışıyordum teeama benim başarısız tuttu. Aferin! +1
Terrance

@Seth Ben de dosya tanımlayıcıları ile oynamayı düşündüm ama teedüzgün görünüyor :)
heemayl

11

En minimalist - yaklaşım # 4 ve # 3, her ikisi de işleve dönüştürülebilir; # 2 benim favorim awk. # 1 scriptkomutu kullanır - genel olarak komut satırını kaydetmek için çok yönlü bir araç; kaydetmek istediğiniz her yerde kullanılabilir.

Yaklaşım # 1:/usr/bin/script Komut satırı çıktısını kaydetmek için, komut istemi ve komutla birlikte her şeyi yakalayan bir komut (varsayılan olarak ubuntu ile birlikte gelir) vardır. Sadece bir komutu ve çıktısını belirli bir dosyaya kaydetmek için flag'i kullanın -cve çıktı dosyasını belirtin. Misal

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

Yaklaşım # 2: awk hackery

Awk sahip system()kabuk komutları çalıştıran izin verir işlevi gelen awkkomut dosyası veya komuta . Çıktı ekranda görünecek, önce komut, sonra çıktı. Gördüklerinizi bir dosyaya yeniden yönlendirmek için >işleci kullanın .

Bu iki şekilde yapılabilir - kullanıcıdan stdin'den veya komut satırı argümanı olarak bir şeyler girmesini isteyin. Birincisi elde etmek daha kolaydır, bu yüzden bunu gönderir.

(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) Komut satırı argümanlar sürümü; Çok uzun cevap vermemek için çıktı dahil değil. Yine, >dosyaya yönlendirmeye ekleyin

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

Yaklaşım # 3: Bash'tan işi sizin için yapmasını isteyin

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

>Operatöre dosyaya yönlendir :

bash -c ' MYCOMMAND="apt-cache depends gnome-terminal"; echo $MYCOMMAND ; $MYCOMMAND ' > output.txt

Yaklaşım # 4: (ikinci favorim)

ByteCommander'ın gönderisinden ilham aldı; readalt kabukta gerekli komutları kullanabilir ve çalıştırabiliriz

read command && (printf "COMMAND: %s" "$command";printf "\n+++++++\n"; sh -c "$command")

Örnek çalışma:

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

Yaklaşım # 5:

Kullanım echoveya here string(aka <<< "string") argümanlar sunmak sh -cyoluylaxargs

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

Ve isterseniz, aynı hileyi bir takma adla kullanabilirsiniz:

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

Güzel, ama Arronical kodunun yaptığı komutu içermiyor.
DK Bose

@DKBose Komutu içerecek başka bir yaklaşım ekleyeceğim. Beş dakika
Sergiy Kolodyazhnyy

@DKBose # 2 yaklaşımım nasıl?
Sergiy Kolodyazhnyy

Bu akıllıca, awkgerçekten çok yapılandırılabilir küçük bir adam değil mi? `script birkaç başka kullanım için de kullanışlı görünüyor.
Arronical

1
Bu en iyi yanıttır, çünkü komut dosyası kullanmak echo, vb. İle görüntülendiğinde kod yürütülebilecek argümanlardan herhangi bir yan etkiyi önler - ikinci, amaçlanan yürütmeyi yapmak, komutun ayrı ayrı çalıştırılmasından farklı sonuçlar verebilmesini sağlar.
Joe

6
  1. Başlat script -q outputfile
  2. Komutunuzu yürütün
  3. Basın Ctrl-D
  4. Dosyayı aç outputfile

Misal

Başlat script

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

Komutunuzu başlatın

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

Basın Ctrl-D

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

Komutunuzu ve çıktınızı gösterin

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

ve böyle bir şey göreceksin

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

5

Takma ad genişletme istiyorsanız (yalnızca bash) şu şekilde yapabilirsiniz:

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 $@
}

Artık koşabilirsin

runcmd acd leafpad > out

4

Daha kolay bir yol olabilir, ancak bunu bir komut dosyasıyla yapabilirsiniz:

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

scriptAna klasörünüzde bu içeriğe sahip bir dosya oluşturun ve yürütme izni verin

chmod +x script

Bu şekilde çalıştırın:

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

Bu yaklaşımın avantajı, isterseniz komut satırını daha sonra tekrar etmeyi kolaylaştırmaktır! Yönlendirmeyi komut dosyasına da yazabilirsiniz, böylece script.shher zaman script.logçıktısıyla adlandırılan bir dosya oluşturur .
Gaurav

4

Tek satırlık bir Bash işlevi kullanan son derece basit bir çözüm

Hazırlık:

Bu yaklaşım, istenen işlevselliği sağlamak için özel bir bash işlevi kullanır. Terminal oturumunuzda aşağıdaki satırı yürüterek tanımlarsınız. aşağıdakiler yerine geçerli bir bash değişkeni adı seçebileceğinizi unutmayın runandlog:

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

Ancak bu yalnızca geçerli Bash oturumu için devam eder, yani terminal penceresini kapattıktan sonra işlev kaybolacaktır.
Yine de denediyseniz ve beğendiyseniz, düzenleyerek~/.bashrc dosyanızı ve bu satırı sonuna ekleyerek dosyayı .

Nasıl kullanılır:

İşlevi tanımladıktan sonra, komutun kendisini ve çıktısını bir dosyaya kaydederken komutları çalıştırmak için kullanabilirsiniz. Hatta, işleve dahil ettiğim kullanıcı veya tam olarak çalıştırıldığı zaman gibi daha fazla bilgi ekleyebilirsiniz. Yorumlarda özellik istekleri kabul edilir! :)

Sözdizimi basittir:

runandlog LOGFILENAME YOUR-COMMAND-WITH-ARGUMENTS

Misal:

Giriş bytecommanderdizininden çalışan kullanıcı olarak örnek bir oturum şöyle görünebilir:

bytecommander: ~ $  runandlog mylogfile fortune
A mathematician is a device for turning coffee into theorems.
        -- P. Erdos

Bu , mevcut dizinde içeriğe sahip yeni bir dosyaya mylogfile (zaten varsa işlev çıktıya ekler!) Sonuçlanır:

[bytecommander] $ fortune 
A mathematician is a device for turning coffee into theorems.
        -- P. Erdos

3

Oldukça amca ama işlevsel bir hile:

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

Çirkin, ama işe yarıyor!


Bu cevabı kabul ediyorum çünkü çözüm daha geniş bir şekilde uygulanabilir.
DK Bose

@DKBose Modülü iki kez yazmanız gerekecek. Ancak bir senaryo ile çözüm gerçekten evrenseldir.
Pilot6

İstediğim şeyi yapsa bile bu cevabı kabul etmem gerektiğine üzüldüm. Umarım umursamazsın!
DK Bose

2
Sorun değil @DKBose, cevabı gönderdiğimde oldukça yetersiz bir çözüm olduğunu biliyordum ve gönderilen alternatif cevaplardan bazı iyi şeyler öğrendim.
Arronik

2

Komutu önce komutu ve daha sonra komutun çıktısını yazdıracak bir işleve geçirebilirsiniz (yönlendirmeler yazdırılan komutun dışında tutulur, tırnakları komuttan kaldırarak ve $@bunun yerine yazdırıp çalıştırarak bunu kolayca değiştirebilirsiniz. arasında $1) işlevinde:

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

bar

Komutu daha sonra eklemek için, dosyanın en son çalıştırılan komutunu ekleyen bu komutu çalıştırabilirsiniz:

<<<"$(<foo)" cat <(history 2 | sed -n '1s/  [0-9][0-9]*  \(.*\)/\1\n/p') - >foo
  • <<<"[...]": burada dize; [...]yönlendirilir cat'in stdin;
  • $(<foo): komut ikamesi; "foo" içeriği ile değiştirilir;
  • cat [...] - >foo: Bitiştirir stdiniçin [...]"foo" ve çıkışları;
  • <([...]): işlem ikamesi: çıktısını içeren bir dosya tanımlayıcı ile değiştirilir [...];
  • history 2 | sed -n '1s/ [0-9][0-9]* \(.*\)/\1\n/p': son iki komutu verir, iki boşluk ve ardından bir veya daha fazla basamak ve ardından ilk satırdan iki boşluk çıkarır ve yazdırır;
$ 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

Neden sadece baskı yapıyorsunuz $1? Ve buna gerek yok eval.
terdon

@terdon Fikir, yönlendirmeleri basılı komutun dışında tutmaktı, çünkü OP'nin durumunda daha güzel görünebileceğini düşündüm. Yine de şimdi değiştirirsem cevabınızla aynı olur. Ancak evet, evalgerekli değil, neden daha önce eklediğimden emin değilim. Teşekkürler.
kos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.