YMMV

YMMV

$ sh copia de seguridad en s3.sh

backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator

ubuntu@accretive-staging-32gb-ephemeral:~$ cat backup-to-s3.sh

#Script to move /home/ubuntu/backup folder  to S3://auto-backup
#Author Ashish Karpe
cd /mnt/backup
filename="bkup_$(date +%Y%m%d_)"
/bin/ls -alF | awk '{ print $9 }'  > /tmp/file

for i in $(cat /tmp/file); do
#       echo $i;
#       read a;
#       echo $filename;
        if [ $filename* = $i ]
        then
                echo "Copying " $i "to S3://auto-backup";
                s3cmd put $i s3://auto-backup

            fi

done

Respuesta1

  1. no lo use forpara iterar sobre las líneas de un archivo, use

    while IFS= read -r line; do ...; done < filename
    
  2. no es necesario canalizar lsla salida a un archivo en absoluto,especialmenteusando-F

  3. use bash [[ x == y ]]para comparar patrones, y el patrón está en el lado derecho:
#!/bin/bash
cd /mnt/backup
prefix="bkup_$(date +%Y%m%d_)"

for file in * .*; do
    [[ -f $file ]] || continue    # skip things like directories and soft links
    if [[ $file == $prefix* ]]; then
        echo "Copying " $file "to S3://auto-backup";
        s3cmd put $file s3://auto-backup
    fi
done < /tmp/file

Respuesta2

Aunque está volcando la salida de 'ls' en un archivo y analizándola, está analizando indirectamente la salida de 'ls', lo cual es problemático, una muy mala idea o ¡MAL! dependiendo de a quién le preguntes.

Aquí está¿Por qué no deberías analizar la salida de 'ls'?!

Aquí estáNombres de archivos y rutas en Shell: cómo hacerlo correctamente!

Por ejemplo, si uno de los archivos tiene un '-' (guión/guión) en el nombre del archivo que no tiene escape (al anteponerle una barra invertida ('\')), podría interpretarse como un parámetro.

Evitar analizar 'ls' puede ser tan simple como;

find . -maxdepth 1 -iname "*"
.
./dont_parse_ls.sh
./array.dat
./.bashrc
./BASH.Indirect.Reference.sh
./basharray.sh
./.forever

Que sale igual que

/bin/ls -alF | awk '{ print $9 }'

./
../
.bashrc
.forever/
BASH.Indirect.Reference.sh
array.dat
basharray.sh*
dont_parse_ls.sh

YMMV

Respuesta3

Hay al menos dos problemas importantes en el guión. Su problema fundamental es el fragmento:

if [ $filename* =

Hay algunos problemas con esto. En primer lugar, en el scripting de shell no se puede "globar" un patrón de coincidencia. Bueno, puedes, pero si fileglob da como resultado más de una coincidencia, obtendrás ambas, en cuyo caso el programa "[" (sí, es un programa) intentará evaluar:

filename1 filename2 filename3 = $i

Funciona si y sólo si fileglob se expande a exactamente un nombre de archivo, y rara vez se puede garantizar eso. En su caso, $filename se expande a al menos un archivo, pero debe tener en cuenta que no siempre es así. Si "$file*" se expande a ningún archivo, es posible (dependiendo de la configuración de la tienda) obtener la cadena vacía:

= $i

lo que hará [que falle. Sin embargo, con la tienda adecuada, obtendrás:

backup-2014-whatever* = $i

Con el *ser parte de la comparación.

El segundo problema fundamental es el uso del -Fparámetro en ls. Esto le indica a ls que agregue al nombre del archivo uno de varios caracteres, dependiendo de si el archivo es un ejecutable, un enlace suave, etc.

NetScr1be ha descubierto algo, pero mira, no tienes que seguir los consejos de NetScr1be y no usar nunca ls... simplemente no usar ls -l. En su lugar, utilice ls -1el cual imprimirá sólo los nombres de los archivos en una sola columna, sin lujos. (Para directorios muy grandes, los ordenará, y esto puede ser un problema, en cuyo caso existe la opción de no ordenar; o use buscar).

Para ser más seguro, sus variables deben estar entre comillas dobles, y tanto LHS como RHS deben tener el prefijo de un carácter ficticio, para asegurarse de que los nombres de archivos extraños que comienzan con a -no lo descarten.

Yo seguiría el consejo de Glenn, más o menos, y lo haría de esta manera:

command ls -1 | while read file; do
    if [ x"$file" = x"$filename" ]]; then 
        echo Do Work Here
    fi
done

Así es como yoharíahacerlo, pero Glenn me informó amablemente que realmente debería hacerlo.suforma:

for file in *; do 
    if [[ $file == $filename ]]; then ...

Respuesta4

Este script hace todo. ¿Por qué no esto? El shell seleccionará los archivos correctos para usted, por lo que no es necesario llamar a ls:

#!/bin/sh
for file in /mnt/backup/bkup_$(date +%Y%m%d)_*
do
    s3cmd put "$file" s3://auto-backup
done
  • El único comando externo es s3cmd.
  • Sin ifdeclaraciones.
  • El único punto de decisión es el forbucle.
  • Fácil de leer.

información relacionada