Ejecute el mismo comando con diferentes parámetros

8

Tengo un programa realmente no permisivo para trabajar. Desafortunadamente, este programa no solo permite lo siguiente

"command -a -b -c"

o

"command -abc"

Así que siempre tengo que escribir lo siguiente

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

Estoy bastante seguro de que hay una forma más eficiente de escribir eso, pero no puedo entenderlo.

Douda
fuente
55
Esto dependerá totalmente del comando. Por favor inclúyalo en su pregunta.
joepd
1
Tienes muchas respuestas diferentes, pero apuesto a que te mantendrás a cmd -a; cmd -b; cmd -clargo plazo, como lo hacen todos los seres humanos.
jimmij
Esta pregunta es demasiado amplia sin detalles sobre command. En general command -a -b -c, command -abcy command -a && command -b && command -ctienen un significado diferente ..
Dmitry Grigoryev

Respuestas:

14

Podrías hacerlo:

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

O:

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

Con algunas conchas.

Pero cuidado con que afecta el stdin de command.

Con zsh:

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

O simplemente:

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

Ninguno de esos abortaría si commandfallara alguna de las invocaciones (excepto si falla con el estado de salida 255).

Para eso, querrás:

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

Eso todavía falla al $?estado de salida de la commandinvocación fallida ). Podrías cambiar eso a:

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

Pero para ese momento, ya es más largo que:

command -a && command -b && command -c
Stéphane Chazelas
fuente
Gracias Stéphane por esta opción. La combinación de !!: 0 y xargs hicieron el truco.
Douda
10

Puede referirse a la primera palabra de la línea de comando anterior ( commanden su caso) por expansión de historial !!:0y luego simplemente puede agregarle los argumentos necesarios.

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

Por ejemplo:

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

Tenga en cuenta que, como ha señalado Stéphane Chazelas , esto también puede dar lugar a expansiones inesperadas.

heemayl
fuente
1
¡Exactamente lo que necesitaba! Muchas gracias heemayl
Douda
2
!!:0(en shells que admiten la expansión del historial de csh) se expandirá a la primera palabra de la línea de comando anterior , no al comando anterior.
Stéphane Chazelas
@ StéphaneChazelas aclaró ..
heemayl
No sabemos cuál fue la primera palabra de la línea de comandos anterior. Intenta ingresar unamey luego echo foobar && !!:0 spamegg && !!:0 baz, eso se expandirá a echo foobar && uname spamegg && uname baz.
Stéphane Chazelas
2
Una !es suficiente: !:0pero con los puntos de @ StéphaneChazelas, es mejor usar !#:0donde la !#media La línea de comando completa escrita hasta ahora .
Costas
3

¿Qué tal una función de shell envolviendo un bucle?

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

Donde "cosa" es el comando real que desea invocar. Entonces simplemente

yourcmd -a -b -c

Incluso puede generalizar esto a cualquier comando:

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

Entonces

splitargs somecommand -a -b -c
kojiro
fuente
1

En medio de las respuestas creativas y perspicaces, aquí hay algo simple en el nombre de escribir menos caracteres:

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

Haga una secuencia de comandos de shell MultiRun , que toma el primer parámetro como comando y lo ejecuta con los parámetros restantes uno por uno.

./ MultiRun curl ABCD

Su script debe tomar curl como comando y ejecutar "curl A", "curl B", "curl C", "curl D". Ahora, debido a que su script está en control, puede decidir si una falla en cualquiera de los comandos terminará el script o continuará con el siguiente parámetro o esperará la entrada del usuario o lo que sea. Incluso puede decidir el estado de salida de todo el script, en función de la ejecución de los comandos individuales.

MultiRun Script puede ser algo como esto:

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

Ahora ejecute esto:
./MultiRun echo 1 2 3 4
para obtener la salida de "echo 1", "echo 2", "echo 3", "echo 4" de esta manera:
1
2
3
4

Es una solución muy flexible y reutilizable.

Prem
fuente