Linux en Espanol
 
Script En Bash (tema #24171)
Publicar nuevo tema  Responder al tema    Foros de discusión -> Programación
Autor Mensaje
ChicaBash
Forista
Registrado: 2011-12-05
Mensajes: 5

Publicado: 2011-12-05 01:17:10    Asunto: Script En Bash

Estoy tratando de crear un script que :
- Limpie la panatalla y luego tome una list de cualquier archivo y por ultimo el nombre de un directorio como argumentos
- por cada una de las condiciones dar el siguiente error:
-- datos incompletos: Imprimir el mensaje apropiado y salir con status 10
-- si el archivo tiene espacios dar un error de mensaje y salir con status 13
-- por ultimo existe el archivo especifico y no es un directorio dar el mensaje apropiado y salir con status 12g
-- Luego mostrar todos los archivo y preguntar al usuario si esta correcto si usuario responde Y proseguir y si responde N entonces dar mensajey salir con status 1

[code:1:2725e261e7]
#!/bin/bash
clear
echo -e "Script Creado por Rosella"


argc=$#
filelist=( "$@" )

dest=${filelist[argc-1]}
unset filelist[argc-1]

printf "%s\n" DESTINATION " $dest"
printf "%s\n" '' FILELIST
printf " %s\n" "${filelist[@]}"

echo -e "\nChecking Files\n"



for i in "${filelist[@]}"
do
echo -n
if test -f $i
then
echo "File $i exists and is not a directory"
fi

if [ ! -f $i ];
then
echo "Error: File $i does not exist"
fi

if test -d $i
then
echo "Error: $i is directory and not a file"
fi

##if test -e $i
##then
## echo "$i exists"
##fi

##if test -r $i
##then
## echo "$i is read-only file"
##fi

##if test -x $i
##then
## echo "$i is executable"
##fi

##if test -s $i
##then
## echo "$i not empty file"
##fi

done
[/code:1:2725e261e7]

pero en este caso estoy teniendo problemas con las condiciones no se porque no funcionan
miguelgf
Forista


Registrado: 2006-12-28
Mensajes: 621

Publicado: 2011-12-05 03:37:39    Asunto:

Hola, ChicaBash.

Bienvenida al foro.

Tu script funciona bien, pero solo en el caso de que los ficheros y directorios carezcan de espacios en sus nombres. Es decir, dado este contenido en el disco:[code:1:42a9b43374]
[yo@maquinita kk]$ ls -l
total 12
drwxr-xr-x 2 yo users 4096 2011-12-05 04:12 cuatro/
-rw-r--r-- 1 yo users 0 2011-12-05 04:12 dos
-rw-r--r-- 1 yo users 0 2011-12-05 04:13 multi palabra
-rwx------ 1 yo users 618 2011-12-05 04:17 script.sh*
drwxr-xr-x 2 yo users 4096 2011-12-05 04:12 tres/
-rw-r--r-- 1 yo users 0 2011-12-05 04:12 uno[/code:1:42a9b43374]

F?jate que hay un archivo cuyo nombre contiene un espacio y se llama "multi palabra". Si lanzo el script para todo lo dem?s, funciona:[code:1:42a9b43374]
[yo@maquinita kk]$ ./script.sh uno dos tres cuatro
Script Creado por Rosella
DESTINATION
cuatro

FILELIST
uno
dos
tres

Checking Files

File uno exists and is not a directory
File dos exists and is not a directory
Error: File tres does not exist
Error: tres is directory and not a file[/code:1:42a9b43374]
Sin embargo, si en la llamada incluyo el fichero cuyo nombre son dos palabras, falla:
[code:1:42a9b43374][yo@maquinita kk]$ ./script.sh uno dos tres multi\ palabra cuatro
Script Creado por Rosella
DESTINATION
cuatro

FILELIST
uno
dos
tres
multi palabra

Checking Files

File uno exists and is not a directory
File dos exists and is not a directory
Error: File tres does not exist
Error: tres is directory and not a file
./script.sh: l?nea 23: test: multi: se esperaba un operador binario
./script.sh: l?nea 28: [: multi: se esperaba un operador binario
./script.sh: l?nea 33: test: multi: se esperaba un operador binario
[/code:1:42a9b43374]

El motivo es sencillo: en tus "if" no has entrecomillado la variable que contiene el nombre del fichero, por lo que cuando el nombre de fichero tiene dos palabras, el "if" lo toma como dos argumentos y no uno.
Por tanto, te basta con cambiar los if de este estilo:
[code:1:42a9b43374] if [ ! -f $i ];[/code:1:42a9b43374]
por esto:
[code:1:42a9b43374] if [ ! -f "$i" ];[/code:1:42a9b43374]
F?jate que al ejecutarse el script, sin comillas se ejecuta:
[code:1:42a9b43374]if [ ! -f multi palabra ];[/code:1:42a9b43374]
es decir le has pasado dos argumentos a "-f", uno es "multi" y el otro es "palabra".
Mientras que al ejecutar con comillas, se ejecuta:
[code:1:42a9b43374]if [ ! -f "multi palabra" ];[/code:1:42a9b43374]
es decir, le pasas un s?lo argumento a "-f", como debe ser.

Saludos.

Miguel.
ChicaBash
Forista
Registrado: 2011-12-05
Mensajes: 5

Publicado: 2011-12-05 03:56:48    Asunto: Hola!

Gracias Miguel me ayudas mucho pero no se que problema de syntax tengo me parece estoy tratando de correr el script y me da problemas no puedo entender que estoy haicendo mal odio los errores de syntax son tan tontos!
miguelgf
Forista


Registrado: 2006-12-28
Mensajes: 621

Publicado: 2011-12-05 04:29:35    Asunto:

Hola.

No hay m?s error de sintaxis que lo que ya te he dicho. Si a los tres "IF" que tienes le pones comillas a "$i", el resultado es correcto:
[code:1:ff000957e9]
[yo@maquinita kk]$ ./script.sh uno dos tres multi\ palabra cuatro
Script Creado por Rosella
DESTINATION
cuatro

FILELIST
uno
dos
tres
multi palabra

Checking Files

File uno exists and is not a directory
File dos exists and is not a directory
Error: File tres does not exist
Error: tres is directory and not a file
File multi palabra exists and is not a directory
[/code:1:ff000957e9]
Saludos

Miguel.
ChicaBash
Forista
Registrado: 2011-12-05
Mensajes: 5

Publicado: 2011-12-05 20:14:47    Asunto:

no puedo hacer q compile no compendo porque :(
RAGNAROK
Forista


Registrado: 2006-01-30
Mensajes: 434

Publicado: 2011-12-05 21:27:46    Asunto:

[quote:698ee7d206="ChicaBash"]no puedo hacer q compile no compendo porque :([/quote:698ee7d206]

Que interprete querr?s decir.

Ayudar?a que pusieses los mensajes de error que te devuelve el script.

Bash suele ser bastante claro en cuanto a la informaci?n de los errores y a su ubicaci?n cuando son fallas en la sintaxis, aunque como dijo Miguel, yo no veo fallas sint?cticas aparte de las ya comentadas.
ChicaBash
Forista
Registrado: 2011-12-05
Mensajes: 5

Publicado: 2011-12-08 03:51:39    Asunto: Hola!

Les agradesco a todos gracias miles! alguien me podria ayudar en que codificar en caso que yo quisisiese que todo este proceso sacara todo lo que sucedio, tales como si hubo errores ? y q files se copiaron a un file de texto ? gracias a todos por su ayuda
miguelgf
Forista


Registrado: 2006-12-28
Mensajes: 621

Publicado: 2011-12-08 04:34:22    Asunto: Re: Hola!

Hola.
[quote:2a302a8bb0="ChicaBash"]Les agradesco a todos gracias miles! alguien me podria ayudar en que codificar en caso que yo quisisiese que todo este proceso sacara todo lo que sucedio, tales como si hubo errores ? y q files se copiaron a un file de texto ? gracias a todos por su ayuda[/quote:2a302a8bb0]

Si quieres que la salida vaya a un fichero de texto, haz lo siguiente:
Define al principio del script una variable con el nombre del fichero y luego cambia todos tus "echo" para a?adirles que den la salida a ese fichero de "log".
As?:[code:1:2a302a8bb0]
#!/bin/bash
...
FICHEROLOG=/tmp/el.nombre.que.se.te.ocurra
....
echo "El proceso se inicio. Crucemos los dedos." > $FICHEROLOG
...
if ... then ...
echo "sucedi? tal error" >> $FICHEROLOG
fi
...
...
if ... then
echo "El proceso auxiliar acab? bien" >> $FICHEROLOG
...
fi
....
echo "Proceso finalizado." >> $FICHEROLOG[/code:1:2a302a8bb0]
F?jate bien en un detalle. La primera vez que redirijo un mensaje a $FICHEROLOG pongo solo un ">" y tooooooooodas las dem?s pongo dos ">>".
El motivo es que con un solo ">" el contenido anteior del fichero se borra y despu?s guarda el mensaje. Con dos ">>", el mensaje es a?adido al final del fichero sin alterar el contenido anterior.
Podr?as tambi?n poner el nombre del fichero en cada "echo" en vez de usar una variable, as?:[code:1:2a302a8bb0]echo "mensaje de tal y cual" >> /tmp/el.nombre.que.se.te.ocurra[/code:1:2a302a8bb0]
Pero eso tiene el problema de empezar a buscar y reemplazar como se te ocurra cambiar de opini?n y querer otro nombre del fichero.
Adem?s, usando una variable, podr?as plantearte que el fichero de log fuera un par?metro, del mismo modo que ya has hecho que el ?ltimo par?metro no signifique lo mismo que los anteriore sino que sea el destino, podr?as hacer que el ?ltimo fuera el log, el pen?ltimo el destino, etc.

Saludos.

Miguel.
ChicaBash
Forista
Registrado: 2011-12-05
Mensajes: 5

Publicado: 2011-12-09 01:39:10    Asunto: Testing

Hola a todos ! :) mira este es mi codigo:

me da un eeror de un parametro desconocido pero no comprendo muy bien que es

[code:1:8622670075]

function ask {
while true; do

if [ "${2:-}" = "Y" ]; then
prompt="Y/n"
default=Y
else [ "${2:-}" = "N" ]; then
prompt="y/N"
default=N
else
prompt="y/n"
default=
fi

# Asking
read -p "$1 [$prompt] " REPLY

# Default Location
if [ -z "$REPLY" ]; then
REPLY=$default
fi

# Reply is valid??
case "$reply" in
Y*|y*) return 0 ;;
N*|n*) return 1 ;;
esac

done
}

declare -i skippeddir=0
declare -i filenumber=0
clear
echo -e "Backup script\nProgramed by Rosella \t\n"


argc=$# ## Arguments On Array
filelist=( "$@" ) ## put all arguments into an array

dest=${filelist[argc-1]} ## Last One In The Array
unset filelist[argc-1] ## Remove Last argument from the array

printf "%s\n" DESTINATION " $dest"
printf "%s\n" '' FILELIST
printf " %s\n" "${filelist[@]}"

echo -e "\nChecking Files\n"



for i in "${filelist[@]}"
do
echo -n
if [ test -f "$i" ]
then
echo "File $i exists and is not a directory"
fi

if [ test -e "$i" ]
then
echo ""
else echo -e "File or directory $i doesn't exist! \n Usage: bkup file1 [file2 ...] bkup_director \n Removing file $i from list and continuing"
unset filelist[$i] ## Remove the file / dir from filelist

fi

if [ test -d "$i" ]
then
echo -e "Error: $i is directory and not a file\n Usage: bkup file1 [file2 ...] bkup_directory"
unset filelist[$i] ## Remove the dir from filelist
skippeddir=$skippeddir+1
fi

done


echo -n
if test -d $dest
then
if ask "Directory $dest exists.

Did U REally Want to use this directory? $dest" Y; then
echo -n ""
else
echo "Terminating Script ..."
exit
fi
else if ask "Directory $dest Doesn't Exist.

Do you wish to create it?" Y; then
echo -e "Creating $dest \n\n ******"
mkdir $dest
echo "Backup by user `whoami` script on `date`" > $dest/BKUP_REPORT.txt
echo "Starting file back up" >> $dest/BKUP_REPORT.txt
printf "%s\n" DESTINATION " $dest" >> $dest/BKUP_REPORT.txt
printf "%s\n" '' FILELIST >> $dest/BKUP_REPORT.txt
printf " %s\n" "${filelist[@]}" >> $dest/BKUP_REPORT.txt
echo -n "" >> $dest/BKUP_REPORT.txt
else
echo "Terminating script ..."
exit
fi
fi


for i in "${filelist[@]}"
do

cp -v $i $dest &>> $dest/BKUP_REPORT.txt
echo "Backed up $i to $dest" >> $dest/BKUP_REPORT.txt
filenumber=filenumber+1

done

filesize=$(du -sh $dest)t
echo "Total files Processed: $filenumber ">> $dest/BKUP_REPORT.txt
echo "Total size of files copied: $filesize" >> $dest/BKUP_REPORT.txt
echo "Number of skipped directories: $skippeddir" >> $dest/BKUP_REPORT.txt

cat $dest/BKUP_REPORT.txt
echo "DONE"

[/code:1:8622670075]

Que sera lo que me falla si entrecomille los If??
miguelgf
Forista


Registrado: 2006-12-28
Mensajes: 621

Publicado: 2011-12-09 16:31:10    Asunto:

Hola.

Por favor, cuando pidas ayuda sobre un error que te est? dando un script, primero intenta leer el error y si no lo entiendes, que a veces los textos de los errores parece que los han escrito como adivinanzas, no pegues s?lo tu c?digo, pega el error que te da y que no puedes interpretar.
He hecho un script con un trocito del tuyo, s?lo la funci?n "ask":
[code:1:7cdc2b9791]#!/bin/bash
function ask {
while true; do

if [ "${2:-}" = "Y" ]; then
prompt="Y/n"
default=Y
else [ "${2:-}" = "N" ]; then
prompt="y/N"
default=N
else
prompt="y/n"
default=
fi

# Asking
read -p "$1 [$prompt] " REPLY

# Default Location
if [ -z "$REPLY" ]; then
REPLY=$default
fi

# Reply is valid??
case "$reply" in
Y*|y*) return 0 ;;
N*|n*) return 1 ;;
esac

done
}
ask "Hola" "Y"
[/code:1:7cdc2b9791]
Lo ejecuto y da un error:
[code:1:7cdc2b9791][yo@maquinita kk]$ ./script.sh
./script.sh: l?nea 8: error sint?ctico cerca del elemento inesperado `then'
./script.sh: l?nea 8: ` else [ "${2:-}" = "N" ]; then'
[/code:1:7cdc2b9791]
El propio mensaje de error te dice que el problema est? en la l?nea 8, que es:
[code:1:7cdc2b9791] else [ "${2:-}" = "N" ]; then[/code:1:7cdc2b9791]
Si hubieras posteado tambi?n la salida de errores que obtienes, sin necesidad de probar nada, te podr?amos haber contestado que en la construcci?n "if...then...else...fi", el "if" lleva "then" pero el "else" no lleva "then", ni ";". Pero como llevas otro "else" tres l?neas m?s abajo, entonces imagino que lo que quer?as era hacer un "if...then...elif then...else...fi". Tu error sigue estando en la l?nea :
[code:1:7cdc2b9791] else [ "${2:-}" = "N" ]; then[/code:1:7cdc2b9791]
Pero no porque le sobre el "; then" sino porque has puesto un "else" donde deber?as haber usado un "elif" (lo que en otros lenguajes se conoce como "elseif").

Arregla eso, prueba de nuevo, y si tienes m?s problemas, postea tambi?n los mensajes de error que obtienes.

Saludos.

Miguel.





La marca registrada Linux (R) se usa siguiendo la sublicensia obtenida del "Linux Mark Institute",
el LICENCIATARIO exclusivo de Linus Torvalds, propietario de la marca en EEUU y otros países
The registered trademark Linux (R) is used pursuant to a sublicense from the Linux Mark Institute,
the exclusive LICENSEE of Linus Torvalds, owner of the mark in the U.S. and other countries