Jalankan perintah yang sama dengan parameter yang berbeda

8

Saya memiliki program yang tidak terlalu permisif untuk bekerja. Sayangnya, program ini tidak hanya mengizinkan yang berikut

"command -a -b -c"

atau

"command -abc"

Jadi saya selalu mengetik yang berikut ini

command -a && command -b && command -c

Saya cukup yakin ada cara yang lebih efisien untuk mengetik itu, tetapi tidak dapat menemukannya.

Douda
sumber
5
Ini akan sangat tergantung pada perintah. Harap sertakan dalam pertanyaan Anda.
joepd
1
Anda memiliki banyak jawaban berbeda, tetapi saya yakin Anda akan bertahan cmd -a; cmd -b; cmd -cdalam jangka panjang, seperti semua manusia.
jimmij
Pertanyaan ini terlalu luas tanpa detail command. Secara umum command -a -b -c,, command -abcdan command -a && command -b && command -cmemiliki arti yang berbeda ..
Dmitry Grigoryev

Jawaban:

14

Anda bisa melakukannya:

echo -a -b -c | xargs -n 1 command

Atau:

xargs -n1 command <<< '-a -b -c'

dengan beberapa kerang.

Namun berhati-hatilah bahwa itu mempengaruhi stdin dari command.

Dengan zsh:

autoload zargs # best in ~/.zshrc
zargs -n 1 -- -a -b -c -- command

Atau sederhananya:

for o (-a -b -c) command $o

Tak satu pun dari mereka akan membatalkan jika salah satu commanddoa gagal (kecuali jika gagal dengan status keluar 255).

Untuk itu, Anda ingin:

for o (-a -b -c) command $o || break

Itu masih gagal ke $?status keluar dari commanddoa yang gagal ). Anda dapat mengubahnya menjadi:

(){for o (-a -b -c) command $o || return}

Tetapi pada saat itu, sudah lebih lama dari:

command -a && command -b && command -c
Stéphane Chazelas
sumber
Terima kasih Stéphane untuk opsi ini. Kombinasi !!: 0 dan xargs berhasil.
Douda
10

Anda bisa merujuk kata pertama dari baris perintah sebelumnya ( commanddalam kasus Anda) dengan ekspansi sejarah !!:0dan kemudian Anda bisa menambahkan argumen yang diperlukan untuk itu.

command -a && !!:0 -b && !!:0 -c

Sebagai contoh:

% echo foobar && !!:0 spamegg && !!:0 baz    
echo foobar && echo spamegg && echo baz
foobar
spamegg
baz

Perhatikan bahwa, seperti yang ditunjukkan oleh Stéphane Chazelas , ini dapat menghasilkan ekspansi yang tidak terduga juga.

heemayl
sumber
1
Apa yang saya butuhkan! Terima kasih banyak heemayl
Douda
2
!!:0(di shell yang mendukung ekspansi sejarah csh) akan diperluas ke kata pertama dari command- line sebelumnya, bukan perintah sebelumnya.
Stéphane Chazelas
@ StéphaneChazelas mengklarifikasi ..
heemayl
Kami tidak tahu apa kata pertama dari baris perintah sebelumnya. Cobalah untuk masuk unamedan kemudian echo foobar && !!:0 spamegg && !!:0 baz, itu akan diperluas ke echo foobar && uname spamegg && uname baz.
Stéphane Chazelas
2
Satu !sudah cukup: !:0tetapi dengan poin @ StéphaneChazelas lebih baik digunakan di !#:0mana !#artinya Seluruh baris perintah diketik sejauh ini .
Costas
3

Bagaimana dengan fungsi shell yang membungkus sebuah loop?

yourcmd() {
    local arg
    for arg; do
        thing "$arg" || return
    done
}

Di mana "benda" adalah perintah aktual yang ingin Anda panggil. Maka sederhananya

yourcmd -a -b -c

Anda bahkan dapat menggeneralisasi ini ke perintah apa pun:

splitargs() {
    local cmd arg 
    cmd="$1"
    shift
    for arg; do
        "$cmd" "$arg" || return
    done
}

Kemudian

splitargs somecommand -a -b -c
kojiro
sumber
1

Di tengah jawaban yang kreatif dan berwawasan luas, ada sesuatu yang sederhana dengan nama mengetik lebih sedikit karakter:

# under the assumption that you have a frequently-used set of flags: -a -b -c
alias c='command -a && command -b && command -c'

# slightly more generally, name some aliases according to the set of flags
alias cabc='command -a && command -b && command -c'
alias cdef='command -d && command -e && command -f'

# more generally, just shorten the command name and then pass whatever flags you want
alias c=command
c -e && c -f && c -f
Jeff Schaller
sumber
0

Buat skrip shell MultiRun , yang mengambil Parameter pertama sebagai Perintah dan menjalankannya dengan Parameter yang tersisa satu per satu.

./ MultiRun curl ABCD

Script Anda harus menggunakan curl sebagai perintah dan menjalankan "curl A", "curl B", "curl C", "curl D". Sekarang, karena skrip Anda dalam kontrol, Anda dapat memutuskan apakah kegagalan dalam satu perintah akan menghentikan skrip atau melanjutkan ke Parameter berikutnya atau menunggu input pengguna atau apa pun. Anda bahkan dapat memutuskan status keluar dari keseluruhan skrip, berdasarkan pada eksekusi perintah individu.

MultiRun Script dapat berupa seperti ini:

#! /bin/bash
COMMAND=$1
shift #### Remove COMMAND from existing Parameters
for PARAMETER in "$@" ; #### Process all remaining Parameters
do
  # echo Executing "$COMMAND $PARAMETER" now #### Uncomment this line to see what command is getting executed.
  $COMMAND $PARAMETER
  # Check exit status and take action or wait for user input , if required.
  # read -p "finished executing command. press enter to continue. waiting..." #### Uncomment this line to pause between commands.
done
# Depending on the individual exit statuses , choose your exit status N with "exit $N".

Sekarang jalankan ini:
./MultiRun echo 1 2 3 4
untuk mendapatkan output dari "echo 1", "echo 2", "echo 3", "echo 4" seperti ini:
1
2
3
4

Ini adalah solusi yang sangat fleksibel & dapat digunakan kembali.

Prem
sumber