En un script, si pongo #!/bin/bash
en la parte superior, esto funcionará bien:
cp directory/{foo,bar} destination
Sin embargo, con sh, esto dará el error "no existe tal archivo o directorio". En sh, ¿hay otra forma de lograr el mismo objetivo final con un comando?
Respuesta aceptada:
Como ha observado, no todos los armazones admiten la expansión de las tornapuntas.
Forma 1:dos caminos separados (es decir, escribir el prefijo dos veces)
Si su objetivo es realmente hacerlo con un solo comando, una forma simple es:
cp directory/file1 directory/file2 destination
El cp
El comando admite varios argumentos de origen seguidos de un argumento de destino. De hecho, eso es lo que está pasando con el comando que te funciona en Bash. Bash realiza una expansión de llaves, que convierte el comando que ha estado usando en el que se muestra arriba. Es decir, cuando ejecuta cp directory/{file1,file2} destination
en Bash, el cp
el comando nunca ve llaves.
Un comando como ese es simple y fácil de entender. Sugiero considerarlo.
Forma 2:Una variable para el prefijo
Pero si su objetivo es evitar repetir usted mismo, entonces es posible que prefiera no hacerlo de esa manera, especialmente si directory
en realidad es un camino largo. Después de todo, si tiene que editar la ruta más adelante en la secuencia de comandos, tendrá que realizar cambios en ambas instancias.
Puede almacenar directory
(o lo que sea, presumiblemente una ruta más larga) en una variable de shell:
dir='directory'
cp "$dir/file1" "$dir/file2" destination
$dir
es la expansión de parámetros. El shell lo reemplaza con el valor contenido en la variable dir
. Al usar la expansión de parámetros, no debe omitir las comillas dobles, excepto en el caso poco frecuente de que desee realizar la división de campos y la ampliación. (Esto también se aplica a Bash).
Esos son dos comandos, pero si su objetivo real es evitar que se repita, eso puede ser lo que quiere. Podrías escribir
dir='directory'; cp "$dir/file1" "$dir/file2" destination
para convertirlo en "un comando", pero eso no es más corto y es un poco menos legible.
(Tenga en cuenta que no puede simplemente eliminar el ;
allí. El resultado de hacer sería un comando bien formado, pero no haría lo que quieres. Ejecutaría el cp
comando, pasando una variable de entorno llamada dir
con el valor directory
en el cp
entorno de mando. Ya que es la concha y no el cp
comando, que expande dir
, esto no funcionaría.)
Forma 3:cd
ig al prefijo
Si su secuencia de comandos no hace nada más después de realizar esta operación, o no importa cuál sea el directorio actual para los comandos posteriores, entonces if destination
es un camino absoluto , puedes usar:
cd directory
cp file1 file2 destination
Pero no lo recomiendo para las secuencias de comandos, a menos que su secuencia de comandos realice acciones posteriores que se beneficien de ejecutarse desde ese directorio, o que se puedan escribir de manera más concisa o simple cuando se ejecuten desde ese directorio. Excepto cuando el directorio desde el que se ejecuta un script es significativo al propósito del guión, confiar en él puede hacer que sea más difícil razonar sobre el guión; además, si el cd
el comando tiene éxito pero el cp
el comando falla, los mensajes de error resultantes pueden no ser del todo esclarecedores. En cambio, menciono la técnica de cd
ing al directorio de origen porque es un patrón útil para interactivo uso de caparazón.
(Como señaló Hannu, puede encerrar cualquier cantidad de comandos juntos dentro de (
)
para ejecutarlos en un subshell y cambios en el entorno del shell, incluido el efecto de cd
, no persistirá después de que se haya ejecutado el comando. Esta es una técnica muy útil, y fue una omisión sustancial que no la haya mencionado. Tenga en cuenta, sin embargo, que esto no mitiga ningún problema relacionado con tener una ruta relativa para destination
.)
Tenga en cuenta que si el cd
el comando falla, los otros comandos seguirán ejecutándose normalmente. Esto podría copiar diferentes archivos que no desea copiar (si hay otros archivos con los mismos nombres en el directorio desde el que se ejecutó el script) o generar mensajes de error confusos. Así que puede preferir:
cd directory && cp file1 file2 destination
El &&
hace que el segundo comando se ejecute solo si el primer comando tuvo éxito. Tenga en cuenta que eso todavía no deshace el efecto de ejecutar el primer comando. Después de que todo se ejecute, seguirá estando en directory
, a menos que lo haya ejecutado en una subcapa con (
)
.