[BASH] Pequeña duda de novato en shell

Iniciado por Lvio, 12 Febrero 2013, 05:56 AM

0 Miembros y 2 Visitantes están viendo este tema.

Lvio

Saludos . Me estoy adentrando en esto de la shell y he visto ejercicios por ahí los he ejecutado y demás y hay uno que no llego a entender y es el siguiente:

Código (bash) [Seleccionar]
#!/bin/bash
mkdir /home/serjk/$idalumno > /dev/null ; echo $?

if [ $?=0 ]; then
echo "El directorio $idalumno se ha creado sin problemas"
fi


y me da esto

Código (bash) [Seleccionar]
mkdir: no se puede crear el directorio «/home/serjk/»: El archivo ya existe
1
El directorio  se ha creado sin problemas


por lo que tengo entendido tiene que crear un directorio dentro de serjk  .
Y mis dudas con estas:

  • Pero porque no me lo crea ?
  • y porque teniendo que $? = 0 y en este caso tengo uno me hace el echo , si he puedo la condición que solo en caso de que sea 0 ?

    Gracias





    [MOD] Usa el botón "Insertar códigos" no uses el de citar para insertar códigos, te he editado otras partes del comentario para que véas que es sencillo formular un buen post.

alister

#1
hola.
buena eleccion. el scriptng de shell es una habilidad basica que resuelve montones de problemas cotidianos.

te cuento
Cita de: Lvio en 12 Febrero 2013, 05:56 AM
Pero porque no me lo crea ?
obvio. lo dice el error: porque ya existe.

haz la prueba tu mismo por comandos a mano y lo veras enseguida:
mkdir /tmp/prueba
mkdir /tmp/prueba

la primera vez no dará error. la segunda, indudablemente sí, el mismo error que ese script.

tambien tienes que fijarte en un datelle de los mensajes de error, que no tiene buena pinta:

home/serjk/

esta claro que $idalumno no está ajustado a nada, cuando presumiblemente se esperaba que contuviera algo, que para eso está ahi:
Citarmkdir /home/serjk/$idalumno

asi que el problema sin duda es ese.

si $idalumno tuviese algun valor, (supongamos que tiene el valor "lvio"), el script estaria creando la carpeta "/home/serjk/lvio" en lugar de "/home/serjk/" la cual ya existe.

y dandole otra vuelta de tuerca, aunque quizas cometo un error de suposición, pero es que esto que te diré me sigue pareciendo un error:
dudo mucho que quieras tener carpetas de otros usuarios ($idusuario) dentro de la carpeta de un usuario (/home/serjk). yo creo mas bien que el code correcto seria:

mkdir /home/$idalumno > /dev/null


Citar
y porque teniendo que $? = 0 y en este caso tengo uno me hace el echo , si he puedo la condición que solo en caso de que sea 0 ?

ese echo $? ahi es una gravisima cagada. si quieres saber el resultado de mkdir, tienes que recoger la variable $? INMEDIATAMENTE DESPUES, pero el echo de por medio arruina la idea, devolviendo siempre un cero, y anulando toda la posibilidad de detectar errores en mkdir.

solucion a todo junto:
Código (bash) [Seleccionar]
#!/bin/bash
echo -n "teclea id de alumno y pulsa enter:" # si no pides idalumno...
read idalumno #...siempre será una cadena nula! dudo que quieras eso.

# fijate que aqui abajo me he cargado el SERJK sobrante
mkdir /home/$idalumno > /dev/null # separo los comandos en dos lineas, por comodidad, asi que me llevo el punto y coma
exit_status_de_mkdir=$?
# recojo el $? y lo paso a una variable para mas comodidad,
# para que no se borre nunca, para poder consultarlo uncluso
# miles de comandos mas tarde, sin haberlo perdido por haber ejecutado
# otros comandos por medio. es muy recomendable hacer esto siempre.
# asi puedes poner montones de comandos por medio sin miedo a romper nada,
# porque ese echo $? de por medio te destrozaba todo, al generar otro exit status
# nuevo y colocarlo en $? machacando al anterior.
# recuerda que en $? solo se guarda el ultimo exit status, asi que procura
# consultarlo y ponerlo a salvo justo despues de un comando si no quieres
# perderlo irreversiblemente for ever

# ahora puedes meter mil comandos aqui sin perder el exit status de mkdir
# ahora puedes meter mil comandos aqui sin perder el exit status de mkdir
echo $exit_status_de_mkdir # antiguamente tenias: echo $?
# ahora puedes meter mil comandos aqui sin perder el exit status de mkdir
# ahora puedes meter mil comandos aqui sin perder el exit status de mkdir

if [ $exit_status_de_mkdir=0 ]; then
  echo "El directorio $idalumno se ha creado sin problemas"
fi
Back 2 business!

Lvio

entonces si no doy valor ninguno a $idalumno--- no me crea nada? .
" para que se solucionase el erro podria decir que $idalumno=carpeta 2? me crearía carpeta 2 no?"

alister

Cita de: Lvio en 12 Febrero 2013, 06:28 AM
entonces si no doy valor ninguno a $idalumno--- no me crea nada? .
" para que se solucionase el erro podria decir que $idalumno=carpeta 2? me crearía carpeta 2 no?"

si $idalumno vale "" (cuando digo "" quiero decir nada)

entonces, segun tu script original donde claramente ponia:


mkdir /home/serjk/$idalumno


el resultado es:


mkdir /home/serjk/


del mismo modo, si prevamente asignamos el valor "elhacker" a la variable idalumno:


idalumno="elhacker"
mkdir /home/serjk/$idalumno


el resultado de evalurar esa expresion en bash obviamente seria:

mkdir /home/serjk/elhacker


estamos hablando de variables y de como funcionan a la hora de sustituirse por sus valores. y esto es lo mas basico de todo en bash. no avances sin ver esto super claro, hasta que no te salga de forma natural.
Back 2 business!

Lvio

#4
Estoy bastante liado con esto... tanto que estoy sacrificando mi sueño (es una asignatura de mi uni)
hice ya un pequeño script:

Código:

> #!/bin/bash
>
> #selección de la bash que deseamos utilizar
>
> #Asignar la variable Papelera a /tmp/borrados
>
> Papelera="/tmp/borrados"
>
> #Mover la salida por pantalla a /tmp/borrados
>
> mv $* $Papelera
>
> #Mostrar por pantalla
>
> echo Ficheros y directorios\: $* enviados a $Papelera
> echo Eliminados $# elementos\: $*
>
> En la terminal previamente creando los ficheros llamados fich1 fich2 fich3
>
> ./rmp fich1 fich2 fich3
>


En el caso de arriba me funciona a la perfección ya que creé con anterioridad papelera luego más abajo pasé unos parámetros (ficheros creados con anterioridad) y los muevo a papelera ... pero lo llamo así $papelera ... el ejercicio que puse lo ví en un tutorial y me sorprendía que $idalumno no tuviera ningún valor ...

quiero hacerlo yo y se me ocurre de la siguiente manera después de que me explicaras ciertas cosas


#!/bin/bash



  mkdir /home/alumnos/carpeta2> /dev/null ?  #indudablemente tu habias puesto mkdir /home/serjk/ pero esque quiero que dentro de serjk me cree yo que se carpeta 2 ,no sería mkdri/home/serjk/carpeta2?
#aun así ejecuto esto y me sale que la carpeta ya existe ... me voy a serjk y carpeta2 no está ..


if [ $?=0 ]; then
echo "El directorio $idalumno se ha creado sin problemas"
fi



alister

#5
si estas creando carpetas con nombres de otros usuarios DENTRO de tu carpeta de usuario, entonces está perfecto.

luego, si pones /home/alumnos/carpeta2 como algo estático, sin variables, lo que pasará es que la primera vez que ejecutes el script, creará la carpeta, pero a partir de la segunda, no creará la carpeta y veras un mensajito de error diciendo que ya existe.

la sintaxis correcta de ese estilo de if, para comparar valores, es la siguiente:

if [ $? == 0 ]

por eso falla la condicion.
como ya has visto, un solo error en un espacio y te la cargas :)
creo que al reciclar codigo tuyo, tambien caí antes en este tipico error xD

PD: no se si te interesa saberlo, pero el comando
mkdir -p
crea una carpeta de forma silenciosa, si no existe, y en caso de que exista, no dice absolutamente nada, ni crea errores, ni nada.

lo usamos constantemente en scripts bash porque a veces nos va a importar un bledo si la carpeta estaba ahi antes o no, simplemente queremos que esté a partir de ahora.

http://linux.die.net/man/1/mkdir
Back 2 business!

Lvio

#6
bueno al final resultó ser así



#!/bin/bash



  mkdir /home/serjk/carpeta5

if [ $?==0 ]; then
echo "El directorio  se ha creado sin problemas"
fi


Darte las gracias sobretodo a estas horas , te estoy muy agradecido macho :P te invitaba a unas cañas..
por cierto para controlar esto se necesitan muchas muchas horas no? , y supongo que muchas frustaciones


alister

una ultima cosa, con la que te voy a insistir una segunda vez

[quote]if [ [color=red]$? == 0[/color] ]; then


espaciado adecuado , o tu script petará de manera inexplicable antes de lo que esperas xDDD

no hay de que.

para ser bueno en cualquier cosa se requiere superar la media de horas de practica. las frustraciones son una decision del que practica. si disfrutas, es un reto, pero no una frustracion. mentalidad hacker aplicada! :)

saludos
Back 2 business!