Tengo un script simple donde el primer argumento está reservado para el nombre del archivo, y todos los demás argumentos opcionales deben pasarse a otras partes del script.
Usando Google encontré este wiki , pero proporcionó un ejemplo literal:
echo "${@: -1}"
No puedo hacer que nada más funcione, como:
echo "${@:2}"
o
echo "${@:2,1}"
Recibo "Mala sustitución" de la terminal.
¿Cuál es el problema y cómo puedo procesar todos menos el primer argumento pasado a un script bash?

"{@:2}"que no funcione, por lo que la respuesta correcta coincide con la anterior.Respuestas:
Utilizar este:
La siguiente sintaxis:
funcionaría bien, pero no se recomienda, porque como ya explicó @Gordon , que al usarlo
*, ejecuta todos los argumentos juntos como un solo argumento con espacios, mientras@conserva los descansos entre ellos (incluso si algunos de los argumentos contienen espacios) ) No hace la diferencia conecho, pero es importante para muchos otros comandos.fuente
#!/usr/bin/env shpor eso tuve problemas. Su ejemplo funciona bien, igual que el anterior, después de que eliminé ese shebang"${@:2}"lugar: el uso*ejecuta todos los argumentos juntos como un solo argumento con espacios, mientras@conserva los descansos entre ellos (incluso si algunos de los argumentos contienen espacios). La diferencia no se nota conecho, pero es importante para muchas otras cosas.echoes perdonar lo suficiente como para concatenarlos por ti; otros comandos podrían no ser tan agradables. No solo use uno u otro: aprenda la diferencia entre*y@, y cuándo usar cada uno. Deberías estar usándolos casi por igual. Un buen ejemplo de cuándo esto será un problema: si$3contiene un salto de línea (\n), se reemplazará con un espacio, siempre que tenga una$IFSvariable predeterminada .echosolo utiliza como un ejemplo - en cuyo caso se deben no pueden ejecutar juntos. En mi experiencia, las situaciones en las que desea que se ejecuten juntas son raras (consulte esta pregunta para ver un ejemplo ) y"$@"casi siempre es lo que desea. Además, el problema que menciona con un salto de línea solo ocurre si$@(o$*) no está entre comillas dobles.$*bastante frecuencia en mis scripts.Si quieres una solución que también funcione en
/bin/shprobarshift [n]desplaza los parámetros posicionales n veces. Ashiftestablece el valor de$1al valor de$2, el valor de$2al valor de$3, y así sucesivamente, disminuyendo el valor de$#uno.fuente
foo=shiftno hace lo que esperaba.foo=$(shift)shift(en shell) no tiene ningún resultado. Simplemente descarta$1y cambia todo hacia abajo. 2)$(...)inicia una subshell, que tiene sus propios argumentos locales. Cambia los argumentos en la subshell, lo que no afecta al padresomecommand "$1" "${@:2}"hace con este método (es decir, cambiar "en línea")?http://wiki.bash-hackers.org/scripting/posparams
Explica el uso de
shift(si desea descartar los primeros N parámetros) y luego implementar el uso masivofuente
Encontré esto buscando algo más. Si bien la publicación parece bastante antigua, la solución más fácil en bash se ilustra a continuación (al menos bash 4) usando
set -- "${@:#}"donde # es el número inicial del elemento de matriz que queremos conservar hacia adelante:Básicamente, el elemento
set -- "${@:3}"emerge de los dos primeros elementos de la matriz, como el desplazamiento de Perl, y conserva todos los elementos restantes, incluido el tercero. Sospecho que también hay una manera de resaltar los últimos elementos.fuente