Esegui lo stesso comando con parametri diversi


8

Ho un programma non molto permissivo con cui lavorare. Sfortunatamente, questo programma non consente solo quanto segue

"command -a -b -c"

o

"command -abc"

Quindi devo sempre digitare quanto segue

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

Sono abbastanza sicuro che ci sia un modo più efficiente per scriverlo, ma non riesco a capirlo.


5
Questo dipenderà totalmente dal comando. Si prega di includerlo nella tua domanda.
Giovedì

1
Hai molte risposte diverse, ma scommetto che ti atterrai a cmd -a; cmd -b; cmd -clungo termine, come fanno tutti gli esseri umani.
Jimmij,

Questa domanda è troppo ampia senza dettagli command. In generale command -a -b -c, command -abce command -a && command -b && command -channo un significato diverso ...
Dmitry Grigoryev il

Risposte:


14

Potresti fare:

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

O:

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

con alcune conchiglie.

Ma attenzione che influenza lo stdin di command.

Con zsh:

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

O semplicemente:

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

Nessuno di questi si interromperebbe se una delle commandinvocazioni falliva (tranne se falliva con lo stato di uscita 255).

Per questo, vorresti:

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

Ciò non riesce ancora allo $?stato di uscita commanddell'invocazione non riuscita ). Puoi cambiarlo in:

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

Ma a quel punto, è già più lungo di:

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

Grazie Stéphane per questa opzione. La combinazione di !!: 0 e xargs ha funzionato.
Douda,

10

Puoi fare riferimento alla prima parola della riga di comando precedente ( commandnel tuo caso) per espansione della cronologia !!:0e quindi puoi semplicemente aggiungere gli argomenti necessari ad essa.

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

Per esempio:

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

Si noti che, come ha sottolineato Stéphane Chazelas , anche questo può comportare espansioni inaspettate.


1
Esattamente quello di cui avevo bisogno! Grazie mille heemayl
Douda,

2
!!:0(nelle shell che supportano l'espansione della cronologia di csh) si espanderà alla prima parola della riga di comando precedente, non al comando precedente.
Stéphane Chazelas,

@ StéphaneChazelas chiarito ..
heemayl

Non sappiamo quale fosse la prima parola della precedente riga di comando. Prova a inserire unamee quindi echo foobar && !!:0 spamegg && !!:0 baz, che si espanderà a echo foobar && uname spamegg && uname baz.
Stéphane Chazelas,

2
Uno !è abbastanza: !:0ma con @ StéphaneChazelas i punti migliori è usare !#:0dove la !#media L'intera riga di comando ha digitato finora .
Costas,

3

Che ne dici di una funzione shell che avvolge un loop?

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

Dove "cosa" è il comando effettivo che si desidera richiamare. Quindi semplicemente

yourcmd -a -b -c

Puoi anche generalizzare questo a qualsiasi comando:

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

Poi

splitargs somecommand -a -b -c

1

Tra le risposte creative e perspicaci, ecco qualcosa di semplice nel nome di digitare meno caratteri:

# 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

0

Crea uno script di shell MultiRun , che accetta il primo parametro come comando e lo esegue con i parametri rimanenti uno alla volta.

./ MultiRun curl ABCD

Lo script dovrebbe prendere l'arricciatura come comando ed eseguire "arricciatura A", "arricciatura B", "arricciatura C", "arricciatura D". Ora, poiché il tuo script ha il controllo, puoi decidere se un errore in uno qualsiasi dei comandi terminerà lo script o continuerà al parametro successivo o attenderà l'input dell'utente o altro. Puoi anche decidere lo stato di uscita dell'intero script, in base all'esecuzione dei singoli comandi.

MultiRun Script può essere qualcosa del genere:

#! /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".

Ora esegui questo:
./MultiRun echo 1 2 3 4
per ottenere l'output di "echo 1", "echo 2", "echo 3", "echo 4" in questo modo:
1
2
3
4

È una soluzione molto flessibile e riutilizzabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.