
Recibo el siguiente error cuando ejecuto el siguiente script:
cp: cannot stat ls
Contenido del guión
#!/bin/bash
#make copies of all files in directory
cd /home/don
LIST='ls'
for i in $LIST; do
ORIG=$i
DEST=$i.old
cp $ORIG $DEST
echo "Copied $i"
done
¿Alguien puede ver el problema?
Respuesta1
Uno de los principales errores es que estás intentando utilizar el ls
comando, pero la variable LIST solo contiene la cadena 'ls'. Puede utilizar la sustitución de comandos con la $(command)
sintaxis. Lo desaconsejaría en este caso, ya que no le brindará información en el formato que pueda usar fácilmente. Casi siempre es unerror al analizar la salida dels
.
En esta circunstancia, debe utilizar la coincidencia de patrones de shell, también conocida comoglobo.
En su lugar, sugeriría el siguiente método en su script:
#!/bin/bash
#make copies of all files in directory
for i in /home/don/* ; do
if [[ -f $i ]]; then
orig="$i"
dest="${i}.old"
cp "$orig" "$dest"
echo "Copied $i"
else
echo "${i} is not a file"
fi
done
- Esto utiliza Shell global para hacer coincidir todos los archivos en el directorio.
./*
significa todo lo que está en el directorio actual (.
). - La
if
declaración verifica si la coincidencia es un archivo (fallará en directorios y enlaces) y realiza la secuencia de copia si lo es. - Cambié los nombres de las variables para que estén en minúsculas, ya que las variables de entorno del sistema están en mayúsculas, por lo que evitará conflictos de nombres no deseados.
Respuesta2
Bueno, hay un pequeño error en tu script. En la cuarta línea querías ejecutarespor lo que no debe estar entre comillas simples, sino que debe estar dentro del símbolo.``. Entonces su script cambia de la siguiente manera
LIST=`ls`
Intente actualizar su script como se indica arriba.
Sin embargo, es aconsejable no utilizarlo $(ls)
en absoluto; debería preferir el shell globbing en el encabezado del bucle.
for i in *; do
como me gustaSr. David AnderssonComenté a continuación que esto podría usarse con comillas para valores variables (" $yo ") para las declaraciones que le siguen, de lo contrario podría generar problemas con los espacios en los nombres de archivos. Puede evitar esto utilizando buscar combinado con sustitución de procesos:
while read l; do
i=$(basename "$l")
done < <(find . -name '*' -maxdepth 1)
A continuación se proporciona una respuesta detallada con guión y explicación.Señor Arronical. Consúltelo para obtener mejores secuencias de comandos en el futuro.
Respuesta3
La versión del comando 'buscar'
Su secuencia de comandos se puede realizar como un find
comando de una sola línea, sin la necesidad de analizar ls
o alterar globs, etc.
Su objetivo, según dice la pregunta, es hacer copias de todos los archivos en el directorio actual. Para eso, el comando apropiado sería:
find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
Lo que esto hace es find
operar en todos los archivos en .
el directorio (actual) y llamar cp
a cada archivo (por lo tanto \;
). Debido a que find
es recursivo, tenemos que limitar la profundidad de la búsqueda, por lo tanto, -maxdepth
marcar y -mindepth
marcar es para evitar aparecer .
como uno de los resultados de búsqueda.
Ejecución de muestra:
$ touch "file one" "file two"
$ find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
$ ls -1
file one
file one.old
file two
file two.old
$
NOTA: cp
todavía se quejará de los directorios. Hay un par de maneras de lidiar con esto.
1) puedes filtrar solo archivos si ese es tu objetivo con -type f
la bandera en find
me gusta
find . -mindepth 1 -maxdepth 1 -type f -exec cp {} {}".old" \;
2) Utilícelo cp -r
también para hacer copias de directorios.
find . -mindepth 1 -maxdepth 1 -exec cp -r {} {}".old" \;
Python de una sola línea
Este es un poco más largo find
, pero aún así hace el trabajo y no tiene problemas con nombres de archivos especiales.
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") for f in os.listdir(".") if os.path.isfile("./" + f)]'
Ejecución de muestra:
$ touch "test file 1" "testfile 2"
$ python -c 'import shutil;import os;[shutil.copyfile(f,f + ".old")
> for f in os.listdir(".")
> if os.path.isfile("./" + f)]'
$ ls -1
test file 1
test file 1.old
testfile 2
testfile 2.old
$
Para incluir directorios, utiliceshutil.copytree(source,destination)
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") if os.path.isfile("./" + f) else shutil.copytree(f,f + ".old") for f in os.listdir(".")]'
Tenga en cuenta que esto fallará si directory_one.old/
ya existe