Führen Sie denselben Befehl mit unterschiedlichen Parametern aus

8

Ich habe ein nicht wirklich freizügiges Programm, mit dem ich arbeiten kann. Leider erlaubt dieses Programm nicht nur Folgendes

"command -a -b -c"

oder

"command -abc"

Also muss ich immer folgendes eingeben

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

Ich bin mir ziemlich sicher, dass es einen effizienteren Weg gibt, das zu tippen, kann es aber nicht herausfinden.

Douda
quelle
5
Dies hängt vollständig vom Befehl ab. Bitte nehmen Sie es in Ihre Frage auf.
Joepd
1
Sie haben viele verschiedene Antworten, aber ich wette, Sie werden sich auf cmd -a; cmd -b; cmd -clange Sicht daran halten, wie es alle Menschen tun.
Jimmyij
Diese Frage ist ohne Details zu weit gefasst command. Im allgemeinen Fall command -a -b -c, command -abcund command -a && command -b && command -chaben unterschiedliche Bedeutung ..
Dmitry Grigoryev

Antworten:

13

Du könntest es tun:

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

Oder:

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

mit einigen Muscheln.

Aber Vorsicht, dass es die stdin von beeinflusst command.

Mit zsh:

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

Oder einfach:

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

Keiner von diesen würde abgebrochen, wenn einer der commandAufrufe fehlschlägt (außer wenn er mit dem Exit-Status 255 fehlschlägt).

Dafür möchten Sie:

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

Dies führt immer noch nicht zum $?Exit-Status des fehlgeschlagenen commandAufrufs. Sie können dies ändern in:

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

Aber zu diesem Zeitpunkt ist es schon länger als:

command -a && command -b && command -c
Stéphane Chazelas
quelle
Vielen Dank an Stéphane für diese Option. Die Kombination von !!: 0 und xargs hat es geschafft.
Douda
10

Sie können auf das erste Wort der vorherigen Befehlszeile ( commandin Ihrem Fall) durch Verlaufserweiterung verweisen !!:0und dann einfach die erforderlichen Argumente hinzufügen.

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

Zum Beispiel:

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

Beachten Sie, dass dies, wie Stéphane Chazelas betont hat , auch zu unerwarteten Erweiterungen führen kann.

heemayl
quelle
1
Genau das, was ich brauchte! Vielen Dank heemayl
Douda
2
!!:0(in Schalen , die CSH Geschichte Expansion unterstützt) wird auf das erste Wort der vorhergehenden command- erweitert Linie , nicht vorheriger Befehl.
Stéphane Chazelas
@ StéphaneChazelas geklärt ..
heemayl
Wir wissen nicht, was das erste Wort der vorherigen Befehlszeile war. Versuchen Sie einzutreten unameund dann echo foobar && !!:0 spamegg && !!:0 bazwird das erweitert echo foobar && uname spamegg && uname baz.
Stéphane Chazelas
2
Eines !ist genug: !:0aber mit @ StéphaneChazelas Punkten ist es besser, dort zu verwenden, !#:0wo der !#Mittelwert Die gesamte Befehlszeile, die bisher eingegeben wurde .
Costas
3

Wie wäre es mit einer Shell-Funktion, die eine Schleife umschließt?

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

Wobei "Ding" der eigentliche Befehl ist, den Sie aufrufen möchten. Dann einfach

yourcmd -a -b -c

Sie können dies sogar auf einen beliebigen Befehl verallgemeinern:

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

Dann

splitargs somecommand -a -b -c
Kojiro
quelle
1

Inmitten der kreativen und aufschlussreichen Antworten ist hier etwas Einfaches im Namen der Eingabe weniger Zeichen:

# 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
quelle
0

Erstellen Sie ein Shell-Skript MultiRun , das den ersten Parameter als Befehl verwendet und diesen mit den verbleibenden Parametern nacheinander ausführt .

./ MultiRun Curl ABCD

Ihr Skript sollte curl als Befehl verwenden und "curl A", "curl B", "curl C", "curl D" ausführen. Da Ihr Skript nun die Kontrolle hat, können Sie entscheiden, ob ein Fehler in einem Befehl das Skript beendet oder mit dem nächsten Parameter fortfährt oder auf Benutzereingaben wartet oder was auch immer. Sie können sogar den Exit-Status des gesamten Skripts basierend auf der Ausführung der einzelnen Befehle festlegen.

MultiRun Script kann ungefähr so ​​aussehen:

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


Führen Sie nun Folgendes aus : ./MultiRun echo 1 2 3 4
, um die Ausgabe von "echo 1", "echo 2", "echo 3", "echo 4" wie folgt zu erhalten:
1
2
3
4

Es ist eine sehr flexible und wiederverwendbare Lösung.

Prem
quelle