-
Notifications
You must be signed in to change notification settings - Fork 0
/
CrontabAdmin_zenity.sh
1521 lines (913 loc) · 95 KB
/
CrontabAdmin_zenity.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# Licence GNU GPL3
# Licencia GNU GPL3
# Free as in freedom, not free as in beer
# d888888b d8b db d888888b d8888b. .d88b. d8888b. db db .o88b. .o88b. d888888b .d88b. d8b db
# `88' 888o 88 `~~88~~' 88 `8D .8P Y8. 88 `8D 88 88 d8P Y8 d8P Y8 `88' .8P Y8. 888o 88
# 88 88V8o 88 88 88oobY' 88 88 88 88 88 88 8P 8P 88 88 88 88V8o 88
# 88 88 V8o88 88 88`8b 88 88 88 88 88 88 8b 8b 88 88 88 88 V8o88
# .88. 88 V888 88 88 `88. `8b d8' 88 .8D 88b d88 Y8b d8 Y8b d8 .88. `8b d8' 88 V888
# Y888888P VP V8P YP 88 YD `Y88P' Y8888D' ~Y8888P' `Y88P' `Y88P' Y888888P `Y88P' VP V8P
# SCRIPT EN BASH, COMODO, FACIL Y SEGURO EN INTRODUCCION DE CONTRASEÑAS PARA USUARIOS QUE DESEAN ADMINISTRAR SUS TAREAS AUTOMATIZADAS DE BACKUP DE BASE DE DATOS O REALIZAR BACKUP MANUALMENTE
# ----------------------------------- INTRODUCCION ------------------------------------
# EL MOTIVO DE ESTE SCRIPT ES HACER UN PROGRAMA AMIGABLE CON EL USUARIO, ESTO ES UN SCRIPT EN BASH (BORN AGAIN SHELL de GNU, como sustituto de Bourne Shell (sh)), PARA FACILITAR A LOS USUARIOS DE WINDOWS QUE TIENEN TERMINALOFOBIA/CONSOLAFOBIA PROPORCIONANDOLES UNA GUI (GRAPHIC USER INTERFACE), ADMINISTRAR SUS TAREAS EN CRONTAB Y HACER BACKUP DE SUS BASES DE DATOS SIN TENER QUE PENSAR NI TECLEAR MUCHO, Y SIN TENER QUE VER LA TERRORIFICA TERMINAL, LES PERMITIRA PROCEDER MEDIANTE MENSAJITOS E ICONITOS.
# el autor de este programa empezo portando el script en Glade, pero posteriormente desecharon todo el trabajo hecho ya que era una tarea complicada por no ser la adecuada, Glide es una buena manera dar interfaz a tus programas en C o C++ pero no es adecuado para scripts en BASH
# importante en sistemas operativos UNIX (Apple OSX...) o UNIX LIKE (GNU...), dar nombres sin espacios, ya que comandos con rutas para intercatuar con archos con espacios en su nombre, delante de cada espacio debemos poner una contrabarra ("\") delante de cada espacio. En vez de espacios utilizaremos "-" o "_" para facilitar el trabajo y evitar problemas.
# Este script se puede hacer mas rapido, con zenity toma su tiempo, pero si el programa se usa a menudo, se ganara mucho tiempo dada su comodidad y estabilidad
# la mayoria de los programadores desecha la opcion de dar GUI a sus scripts en bash, ya que por ejemplo con zenity la realizacion de script toma bastante mas tiempo y programacion se vuelve mas engorrosa, a parte comentar y documentar el programa toma bastante mas tiempo
# ----------------------------------- FIN INTRODUCCION -------------------------------
# por seguridad, variables de entorno (PATH, EDITOR, SHELL, ...) y otras internas variables de shell (BASH_VERSION, RANDOM, ...) son totalmente capitalizadas, todas las demas demas variables deberian declararse en minusculas, porque todas las variables son sensitivas a minusculas/mayusculas, esto evitara accidentalmente sobreescribir variables de entorno internas del sistema
# ------------------ lo siguiente es un codigo que comprobamos si el usuario tiene privilegios de superusuario o no ------------------------- OMITIDO
# pero se omite este codigo por que almacenaremos directamente nuestra contraseña de superusuario en una variable y ejecutaremos comandos con "sudo" y la contraseña introducida
# controlamos si lo ejecutamos como superusuario, si no es asi, escupimos un mensaje en output/consola y detenemos la ejecucion, ya que los archivos con los que vamos a interactuar estan protegidos contra la modificacion por un usuario, tambien interactuaremos con los servicios del sistema que tambien necesitaran permisos de superusuario
# if [ "$(id -u)" != "0" ]; then
# Escupimos el mensaje de error en zenity de que no estamos usando el script como superusuario, por lo tanto no nos dejaria editar nada si no es asi, y finalizamos el programa
# zenity --width=350 --height=120 --error --title="Error de privilegios" --text "Este script debe ejecutarse como superusuario, vuelve a ejecutarlo escribiendo en la consola 'sudo su' y introduce tu contraseña"
# lo mismo que lo anterior pero en terminal en vez de en zenity
# echo "Este script debe ejecutarse como superusuario, vuelve a ejecutarlo escribiendo en la consola 'sudo su' y introduce tu contrasena" 1>&2
# exit 1
# fi
# lo anterior es incomodo para el usuario, ya que tendra que volver a ejecutar el programa, por lo tanto omitimos este codigo, ya que controlaremos permisos de una forma mas comoda y efectiva
# a partir de ahora simplemente ejecutaremos cualquier comando que requiera privilegios de superusuario con nuestro usuario pero con "sudo"
# variable donde almacenaremos la contraseña introducida por el usuario
# PASSWD="$(zenity --password --title="Introduce contraseña de superusuario")"
# comando de prueba de si tenemos privilegios de superusuario
# tambien ejecutaremos a partir de ahora todos los comandos con sudo y la contraseña para usuario
# echo -e $PASSWD | sudo -S whoami
# omitimos declarar variables en castellano que lleven "ñ" para evitar problemas, de alli llamar variable de la contraseña como "password" y no "contraseña"
# usamos una funcion, ya que nos ahorrara lineas del mismo codigo, para no tener que poner lo mismo todo el rato
####### # # # # ##### ### ##### # # ####### #####
# # # ## # # # # # # ## # # # #
# # # # # # # # # # # # # # #
##### # # # # # # # # # # # # ##### #####
# # # # # # # # # # # # # # #
# # # # ## # # # # # # ## # # #
# ##### # # ##### ### ##### # # ####### #####
# PARA DECLARAR LAS FUNCIONES CORRECTAMENTE, SE DECLARAN CON () AL FINAL DEL NOMBRE DE LA FUNCION, () SOLO AL DECLARAR, AL LLAMAR A UNA FUNCION SOLO PONDREMOS SU NOMBRE
# ---------------------------------- FUNCION COMPROBAR CONTRASEÑA ------------------------------------------
function comprobar_password() {
# declaramos una variable donde emteremos el nombre del usuario (que esta usando este script)
mi_usuario="$USER"
# almacenamos en una variable el texto de salida "sudo"
test_sudo="$(groups | grep sudo)"
# si la variable anterior se quedo vacia, es que el usuario que ejecuta el script no tiene permisos administrativos
if [ -z "$test_sudo" ]; then
# le avisamos a traves de zenity de que el usuario no tiene permisos administrativos
zenity --width=400 --height=120 --error --window-icon="info" --text="${mi_usuario}, no tienes permisos administrativos, por lo tanto hay comandos que no podras ejecutar"
fi
# mostramos mensaje especifico para introduccion de la contraseña en zenity
# variable donde almacenaremos la contraseña introducida por el usuario
# password="$(zenity --password --title="Introduce la contraseña de usuario")"
# IMPORTANTE: por seguridad en las distribuciones GNU+Linux, la contraseña o/y usuario root estan desactivados con por ejemplo comando "#passwd -l root" ("#passwd -u root" hara lo contrario), que bloqueara/desactivara la cuenta root y su contraseña, esto se hace por seguridad, en distribuciones como Ubuntu que por defecto root estara desactivado, tambien su hash y contraseña. Por lo tanto necesitaremos hacer lo mas portable y compatible nuestoro programa, usando la cuenta de usuario que ejecuto el programa pero con permisos administrativos. Se ha recapacitado y he modificado el programa para que no pida la contraseña de root, sino la de usuario con permisos administrativos (cuando el usuario ejecuta comandos con sudo). Con esto nos evitaremos muchos dolores de cabeza e incompatibilidades, ganaremos portabilidad. No necesitaremos la cuenta root para nada.
# si usuario responde con boton ACEPTAR
if password="$(zenity --password --title="${mi_usuario} introduce tu contraseña")"; then
# si usuario pulsa boton fisico del teclado ENTER o pulsa ACEPTAR en el boton del programa, se dara un mensaje de informacion, y sin perder el tiempo desaparecera en un segundo
zenity --info --text "Enseguida comprobaremos su contraseña" --timeout=1
# si el usuario pulsa CALCEL
else
# si el usuario pulsa cualquier otro boton (en este caso solo CANCELAR es posible), se finalizara el programa
hasta_luego
fi
# una finalizacion intencionada y correcta se llama con "exit 0", "exit 1" se usa si algo va mal y se aborta el programa
# controlamos que el usuario haya introducido algo, si no introdujo nada, ejecutaremos siguiente codigo (mientras contraseña este vacia o sin ningun caracter)
while [[ $password == "" ]]; do
# mostramos en zenity mensaje de error especifico, para forzar al usuario a introducir algo
zenity --width=400 --height=200 --error --title="Error de contraseña" --text "Introduce algo o finaliza el programa"
# forzamos a que el usuario vuelva a introducir algo
password="$(zenity --width=400 --height=120 --password --title="${mi_usuario} introduce de nuevo tu contraseña")"
# si el usuario decide pulsar boton CANCELAR del programa, se finalizara la ejecucion y se saldra del programa, aunque tambien se puede salir con boton X de arriva de la ventana, que esta en el mismo decorador d elas ventanas que se este usando
if [[ $? == 1 ]]; then
exit 0
fi
done
# para saber que linea de codigo estamos ejecutando, para depuracion nos puede servir el siguiente mensaje
#zenity --info --text "Pasamos a la fase de comprobacion de la contraseña"
# usamos programas "getent" y "cut", para obtener contraseña hasheada desde campos GECOS (caracterisitcos de UNIX), con el "cut" recortamos la contraseña hasheada
# tipicamente son datos acerca de usuario que se graban en UNIX
# mas informacion en:
# https://en.wikipedia.org/wiki/Gecos_field
# minombredeusuario:x:1000:1000:usuario,,,:/home/minombredeusuario:/bin/bash
# | | | | | | |
# | | | | | | Autentificador de shell
# | | | | | Home directory
# | | | | Campos GECOS (nombre entero, etc...)
# | | | ID de grupo primario
# | | ID de usuario
# | Indicador de contraseña encriptada
# Nombre de usuario
# no confundirse con ID real de usuario con ID efectiva
# mas acerca de IDs de usuario en:
# https://es.wikipedia.org/wiki/Identificador_de_usuario
# las contraseñas en GNU (sistema operativo incorrectamente llamado como Linux) (sistema operativo UNIX-LIKE) no son enriptadas, sino se usa una funcion criptografica hash
# mas informacion en:
# https://es.wikipedia.org/wiki/Funci%C3%B3n_hash_criptogr%C3%A1fica
# En GNU por defecto se utiliza SHA512 (contraseñas hasheadas empezando por "$6$") para hashear la contraseña del usuario
# si hay curiosidad de comprobar de verdad que estamos usando SHA512 ejecutamos siguiente comando que nos dara el valor de la variable "ENCRYPT_METHOD":
# $cat /etc/login.defs | grep ENCRYPT_METHOD
# ID | Method
# ─────────────────────────────────────────────────────────
# 1 | MD5
# 2a | Blowfish (not in mainline glibc; added in some
# | Linux distributions)
# 5 | SHA-256 (since glibc 2.7)
# 6 | SHA-512 (since glibc 2.7)
# en nuestro caso utilizaremos la SHA512 y la indicaremos con "$6$"
# atencion, se usa glibc, en algunas distribuciones podria ser diferente ya que en vez de "glibc" se usa "musl" (que es una libreria c diferente, con musl tambien tendriamos problemas con programas compilados sin codigo fuente disponible (software privativo), ya que son binary-only y no podriamos compilarlos para musl, al no disponer de codigo fuente)
# matematicamente es imposible componer la contraseña real partiendo de hash. La verificacion esta hecha criptografiando a hash la contraseña que introduce el usuario y comparandola con la que ya esta criptografiada en el sistema. Si coinciden, el usuario es autentificado. (ver las formulas mas adelante)
# "getent" es un programa de UNIX que ayuda a obtener entradas de archivos de texto importantes del sistema llamados base de datos. Esto incluye archivos de texto como "passwd" y bases de datos de grupos los cuales almacenan informacion acerca de cada usuario, "getent" es un programa corriente para ver detalles de usuarios en UNIX
# mas informacion de uso en:
# https://linux.die.net/man/1/getent
# como nos interesa el hash de la contraseña de superusuario, directamente ponermos "usuario", recortamos usando delimitador "-d" (le indicamos que nuestro delimitador es "$"), y con "-f" (con el 3 seleccionaremos solo campo delimitado numero 3) seleccionamos solamente campo indicado
# a la vez ambas contraseñas son almacenadas en su correspondiente variable cada una
# indicamos con "cut" que recortaremos desde el caracter que esta despues de "$" hasta el siguiente "$" (ambos "$" sin incluir) ("$" es un caracter delimitador que le hemos indicado) (si le damos valor al delimitador, el delimitador no se incluye)
# si antes de un delimitador (en nuestro caso "$") hay al menos un caracter, se contara como un campo, por lo tanto sera campo numero 1
# con el "getent" obtenemos campos GECOS de usuario "usuario" (que seria informacion completa)(importante ejecutar con poderes de superusuario ya que sino, no nos dara la contraseña hasheada la que esta ya almacenada)
# con propiedad "shadow" indicaremos que nos extraiga contraseña hasheada desde archivo "shadow" (que esta en /etc/) (para ver contenido de shadow hace falta permisos de superusuario), y no desde archivo "passwd" (que lo uno que mostrara es un "x" en el campo de la contraseña)
# seria un riesgo de seguridad que se pudiese obtener contraseña hasheada sin permisos de superusuario, por lo tanto un usuario sin permisos de superusuario solo podra ver una y bonita "x"
# mas acerca de contraseñas UNIX y formatos de archivo shadow en:
# http://www.tldp.org/LDP/lame/LAME/linux-admin-made-easy/shadow-file-formats.html
# contraseñas hasheadas con MD5 empiezan con $1$ y las hasheadas con SHA512 empiezan con "$6$"
# con este comando obtenemos solo una parte (que siempre se mantiene siendo la misma) de contraseña hasheada de usuario desde shadow (ya que si directamente la tomamos completa sera un riesgo de seguridad, y no interesa)
# generalmente no necesitaremos ejecutar este comando con "sudo"
# para obtener nuestro SALT
password_hash_corto=$(gksudo getent shadow ${mi_usuario} | cut -d$ -f3)
# sabiendo donde esta nuestra contraseña hasheada por los campos GECOS
# indicamos con "-d:" que nos obtenga la contraseña hasheada delimitando con ":" y indicamos con "-f2" que nos extraiga el campo delimitado numero 2
# en la variable "password_hash_completo" almacenaremos contraseña hasheada completa de usuario desde shadow, pero no la expondremos directamente por seguridad, sino que la compararemos mas adelante con la que criptografiaremos nosotros en combinacion de contraseña que introdujo el usuario ("password") y una parte de de contraseña ya hasheada de usuario desde shadow, con lo cual ganaremos en seguridad
# PASSWORD_USUARIO_INTRODUCIDO_CRUDO + PARTE_HASH_CONTRASEÑA_USUARIO_SHADOW ---> ENCRIPTAR = HASH DE CONTRASEÑA COMPLETO DE USUARIO GENERADO
#
# COMPARAR ---> HASH DE CONTRASEÑA COMPLETO DE USUARIO GENERADO "con" HASH DE CONTRASEÑA COMPLETO EXTRAIDO DESDE SHADOW = ¿COINCIDE? ----> AUTENTIFICADO
# L_________---> NO AUTENTIFICADO
# de este modo sabremos que lo que introdujo el usuario es la contraseña correcta
# por lo general no deberiamos tener problemas al ejecutar este comando sin "sudo"
password_hash_completo=$(gksudo getent shadow ${mi_usuario} | cut -d: -f2)
# importamos y ejecutamos funcion de criptografia en Python, criptografiamos nuestro password introducido por el usuario, y lo almacenamos en una variable, el que esta ya hasheado tambien lo almacenamos en una variable a parte
# mas acerca de funcion "crypt" de Python en:
# https://docs.python.org/2/library/crypt.html
# metemos la variable de contraseña sin hashear "password" que introdujo el usuario y tambien metemos la variable donde habiamos almacenado una parte de nuestra contraseña hasheada de usuario desde shadow, la parte que siempre sera la misma, tambien indicamos con "$6$" que queremos obtener un hash en SHA512 especificamente
# almacenamos HASH_COMPLETO_OBTENIDO
# hash_completo_generado=$(python -c 'import crypt; print crypt.crypt("'"${password}"'", "$6$'${password_hash_corto}'")')
# evitamos el anterior comando ya que inyecta datos importantes en la funcion de python. Le pasamos los datos de un modo correcto y mas seguro, como argumentos o a traves de variables de entorno, en nuestro caso usaremos como argumentos
# sino, pasa lo mismo que con inyecciones de sql, mas informacion en:
# https://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL
# con este comando deberiamos obtener un hash completo de la contraseña de usuario, que mas adelante compararemos con el hash de la contraseña de usuario ya extraida desde shadow
hash_completo_generado=$(python -c 'import sys,crypt; print crypt.crypt(sys.argv[1], "$6$"+sys.argv[2])' "$password" "$password_hash_corto")
# en la siguiente linea comprobamos si las contraseñas criptografiadas coinciden, comparamos el resultado de nuestra contraseña ya criptografiada en SHA512 con la que hemos extraido del shadow que tambien esta en SHA512, con lo cual para autentificarse deben coincidir completamente
if [ "${hash_completo_generado}" == "${password_hash_completo}" ]; then
# si el usuario ha introduciro contraseña correcta, felicitamos al usuario por la correcta introduccion de la contraseña a traves de mensaje de informacion de zenity y demonio de notificaciones "notifyd" opcionalmente
# zenity --notification y notify-send, ambos comandos usan demonio notifyd (diferentes distribuciones GNU con diferentes escritorios, pueden utilizar diferentes servicios de notificacion, podrias ser incompatibles con el script para mostrar notificaciones)
# mas acerca de notificaciones de escritorio:
# https://wiki.archlinux.org/index.php/Desktop_notifications_(Espa%C3%B1ol)
zenity --width=400 --height=120 --info --window-icon="info" --text="La contraseña de ${mi_usuario} es correcta\\n¡BIENVENIDO!" --timeout=1
# mensaje que va directo con notify-send
# notify-send "Se estan usando privilegios de superusuario"
fi
# bucle while, mientras la contraseña sea incorrecta (cuando las dos contraseñas, la introducida encriptada y la extraida de campos GECOS encriptada no coinciden)
# cuando el usuario introduce una contraseña incorrecta, ejecutamos un bucle while, hasta que el usuario introduce una contraseña correcta o finaliza el programa con boton CANCELAR de la ventana
while [ "${hash_completo_generado}" != "${password_hash_completo}" ]; do
# mensaje de depuracion, se puede emitir, ya que solo muestra mensaje en terminal
echo "contraseña para ${mi_usuario} incorrecta"
# mostramos un mensaje especifico de error, avisando de que el usuario introdujo una contraseña incorrecta
zenity --width=400 --height=120 --error --title="Error de introduccion" --text "La contraseña de ${mi_usuario} es incorrecta"
# si el usuario pulso sobre boton SI, se volvera a correr el bucle while, volviendo a ejecutar la funcion
if zenity --width=400 --height=120 --question --text="¿Quieres volver a intentarlo?" --ok-label="Si" --cancel-label="No"; then
# zenity --info --text "VOLVEMOS A INTENTAR CON OTRA CONTRASEÑA"
# volvemos a ejecutar la funcion
# no es importante (en este caso), pero terminamos la funcion con return, porque se volvera a llamar de nuevo
comprobar_password; return
# si el usuario pulsa boton NO, se finalizara el programa
elif [[ $? == 1 ]]; then
hasta_luego
fi
done
}
# ---------------------------------- FIN DE LA FUNCION COMPROBAR CONTRASEÑA ---------------------------------------------
# --------------------------------- FUNCION VOLVER A REALIZAR TAREA ------------------------------------------------------
# necesitamos esta funcion, por si el usuario decide realizar otra tarea mas
function volver_realizar_tarea() {
# preguntamos al usuario de si quiere realizar otra tarea en zenity
# si el usuario pulso sobre boton SI, entonces finalizaremos instancia de menu_principal y llamaremos de nuevo a menu_principal
if zenity --width=400 --height=120 --question --text="¿Quieres volver a realizar otra tarea?" --ok-label="Si" --cancel-label="Salir del programa"; then
# finalizamos la instancia de menu_principal y volvemos a llamar a la funcion, para que el usuario eliga una tarea diferente
menu_principal; return
# si el usuario pulsa boton NO, se finalizara el programa
elif [[ $? == 1 ]]; then
hasta_luego
fi
}
# --------------------------------- FIN FUNCION VOLVER A REALIZAR TAREA ------------------------------------------------------
# ------------------------------ FUNCION DESPEDIDA --------------------------------------------------------
function hasta_luego() {
# nos despedimos con un educado mensaje en zenity, con duracion de 1 segundo
zenity --width=400 --info --text "Hasta luego" --timeout=1
# terminamos la ejecucion del programa
exit 0
}
# ---------------------------- FIN FUNCION DESPEDIDA ------------------------------------------------------
# ----------------- FUNCION MENU PRINCIPAL ----------------------
# necesitamos meter el menu principal en una funcion, porque si al usuario se le olvida seleccionar opcion, daremos un mensaje de error en zenity y volveremos a ejecutar la funcion de menu principal de nuevo, de este modo controlaremos este suceso incomodo de tener que volver a ejecutar el programa
function menu_principal() {
# con valor FALSE en cada opcion indicamos que todos los radiobuttons estan sin seleccion (ninguno esta activado)
# en la siguiente linea llamamos a zenity y al principio le asignamos una variable que nos servira para almacenar string seleccionado por usuario como respuesta, tambien personalizamos los botones de cancelar (que programaremos como "SALIR), y de OK (que programaremos como "EJECUTAR TAREA")
menu_principal_respuesta=$(zenity --width=550 --height=380 --list --title "Editor de tareas automatizadas de base de datos" --text "Selecciona tarea a realizar: " --radiolist --column "" --column "Tarea" --ok-label="Ejecutar tarea" --cancel-label="Salir" \
FALSE "Obtener lista de tareas automatizadas programadas" \
FALSE "Programar fecha de backup automatizada" \
FALSE "Borrar tareas automatizadas" \
FALSE "Hacer backup de base de datos manualmente ahora" \
FALSE "Reiniciar demonio de Crontab" \
FALSE "Ayuda en crontab" \
FALSE "Licencia" \
FALSE "SALIR"); boton_control=$? # declaramos variable que controla boton "EJECUTAR TAREA" y "SALIR" aqui mismo, ya que sino mas adelante se pierde, se pierde porque ya estamos metiendo valores "boton pulsado"(int) y "respuesta de radiobutton seleccionada"(string) ambos en la misma variable, los dos valores en la variable "MENU_PRINCIPAL_RESPUESTA" y crean conflicto, con lo cual perdemos despues valor que nos devuelve el boton (1 o 0)
# comandos para la depuracion, para ver que valores estamos almacenando (se mostraran en la terminal donde se esta ejecutando el script)
echo "$boton_control"
echo "$menu_principal_respuesta"
# controlamos que boton ha pulsado el usuario
# si pulsa boton "SALIR", devuelve valor del boton por defecto un 1
if [ $boton_control == 1 ]; then
# si usuario pulsa boton "SALIR" en el boton del programa, se dara un mensaje de informacion de despedida, y sin perder el tiempo desaparecera en un segundo
hasta_luego
# si el boton pulsado por el usuario es "REALIZAR TAREA", se devolvera boton con valor 0
elif [[ $boton_control == 0 ]]; then
# controlamos con un if y un operador "-z" que comprueba que nuestra variable esta vacia (valor null), si el usuario no ha eleccionado ninguna opcion del menu principal
if [[ -z "$menu_principal_respuesta" ]]; then
# si el usuario no ha seleccionado ninguna opcion, se le dara un aviso con un mensaje en zenity, y se volvera a ejecutar funcion de menu principal desde el principio
zenity --width=400 --height=120 --error --title="Error de seleccion" --text="No has seleccionado nada, por favor, selecciona una opcion"
# mensaje de depuracion
zenity --info --text "ejecutamos la funcion menu de nuevo" --timeout=1
# volvemos a ejecutar la funcion, pero no olvidamos de poner "return" para matar la instancia que ya se estaba ejecutando, ya que no usamos bucle "while" aqui
# si no ponemos "return" y usuario no escoge ninguna opcion 3 veces, la ejecucion tendra 3 instancias y mostrara el menu principal 3 veces, con lo cual queremos controlarlo
menu_principal; return
fi
# mensaje de depuracion
# zenity --info --text "ejecutamos select case" --timeout=1
# mensaje de depuracion
echo "$menu_principal_respuesta"
# ejecutamos un select case para controlar la tarea seleccionada por el usuario
# para ello usamos la variable $MENU_PRINCIPAL_RESPUESTA donde hemos almacenado lo que selecciono usuario al ver menu principal
case "$menu_principal_respuesta" in
"Obtener lista de tareas automatizadas programadas" )
# llamamos a la funcion menu_case1
menu_case1
;;
"Programar fecha de backup automatizada" )
# llamamos a la funcion menu_case2
menu_case2
;;
"Borrar tareas automatizadas" )
# llamamos a la funcion menu_case3
menu_case3
;;
"Hacer backup de base de datos manualmente ahora" )
# llamamos a la funcion menu_case4
menu_case4
;;
"Reiniciar demonio de Crontab" )
# llamamos a la funcion menu_case5
menu_case5
;;
"Ayuda en crontab" )
# llamamos a la funcion menu_case6
menu_case6
;;
"Licencia" )
# llamamos a la funcion menu_case7
menu_case7
;;
"SALIR" )
# llamamos a la funcion menu_case8
menu_case8
;;
esac
fi
}
# ----------------- FIN FUNCION MENU PRINCIPAL ----------------------
# ---------------- FUNCION MENU CASE 1 ------------------------------
function menu_case1() {
# declaramos una variable de directorio, atencion con espacios en rutas o nombres de archivo en UNIX (en este caso utilizaremos variable global de entorno)
# si nuestra variable de entrono ($HOME) esta rota, puede que no funcione el programa
# mas informacion en:
# https://wiki.archlinux.org/index.php/environment_variables
dir_cron_list="$HOME/.CrontabAdmin-cycled/"
# controlamos de que el directorio existe
if [ ! -d "$dir_cron_list" ]; then
# si el directorio no existe, lo creamos
mkdir "$dir_cron_list"
# escupimos este mensaje de informacion al usuario en zenity de que no existe el directorio y que se crea uno nuevo
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Se creo el directorio: \\n ${dir_cron_list} \\n para almacenamiento ya que no se encontro"
# mensaje de depuracion
echo "${dir_cron_list} no se encontro este directorio de almacenamiento para el programa, el directorio se ha creado de nuevo"
fi
# entrada al directorio "$HOME/backups-base-de-datos/" de la variable DIR, usamos "|| exit" para controlar en caso de que "cd" pueda fallar por falta de permisos, directorios inexistentes o links simbolicos rotos
# exit sirve para abortar inmediatamente
cd "$dir_cron_list" || exit
#> ${NAME}
# por si acaso si existe ya el archivo temporal, lo borramos para evitar conflictos
if [ -e temp-crontab.txt ]; then
rm temp-crontab.txt
fi
# es importante interactuar con comandos de cron y no con sus archivos directamente, ya que sino tendremos perdidas de tareas programadas tras reiniciar el demonio o el sistema
# almacenamos lo que nos devuelve el comando "crontab -l" que sirve para ver las tareas que ya tenemos programadas
cron_texto=$(crontab -l)
# crontab -l > temp-crontab.txt
# creamos un archivo de texto temporal para almacenar output de "crontab -l"
touch temp-crontab.txt
# pasamos el output de "crontab -l" a nuestro archivo de texto temporal
# atencion con operadores ">" y ">>", ya que uno añade y otro borra todo lo que contiene el archivo de texto ademas de añadir despues lo que queriamos pasar
echo "$cron_texto">temp-crontab.txt
# echo "$string_tarea" >> temp-crontab.txt
# mensaje de depuracion, para ver que tenemos algo dentro
echo "---"
echo "$cron_texto"
echo "---"
# si no hay nada dentro de la variable (en este caso si no hay nada en nuestras tareas de crontab), avisamos al usuario
if [[ -z "$cron_texto" ]]; then
# avisamos al usuario con un mensaje de informacion en zenity
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="No tienes ninguna tarea programa"
# si el usuario pulso sobre boton SI, entonces ira al caso 2 de menu principal
if zenity --width=400 --height=120 --question --text="¿Quieres programar una tarea ahora?" --ok-label="Si" --cancel-label="No"; then
# llamamos a la funcion de programacion de tareas automatizadas desde aqui
menu_case2
# por si acaso si existe ya el archivo temporal, lo borramos para evitar conflictos
if [ -e temp-crontab.txt ]; then
rm temp-crontab.txt
fi
# si el usuario pulsa boton NO, se finalizara el programa
#elif [[ $? == 1 ]]; then
# exit 0
#fi
#menu_case1; return
else
# por si acaso si existe ya el archivo temporal, lo borramos para evitar conflictos
if [ -e temp-crontab.txt ]; then
rm temp-crontab.txt
fi
volver_realizar_tarea
fi
fi
# el siguiente codigo se ejecutara en caso de que tengamos ya laguna tarea programada en la lista
# mostramos en zenity una ventana con informacion, con archivo de texto importado
if zenity --text-info \
--title="Tareas ya programadas" \
--filename=temp-crontab.txt \
--ok-label="Ir al menu principal" --cancel-label="Salir del programa"; then
# eliminamos nuestro archivo temporal, donde habiamos almacenado output de "crontab -l", ya no lo necesitamos
rm temp-crontab.txt
# volvemos a nuestro directorio de partida
cd || exit
menu_principal; return
else
# por si acaso si existe ya el archivo temporal, lo borramos para evitar conflictos
if [ -e temp-crontab.txt ]; then
rm temp-crontab.txt
fi
hasta_luego
fi
# volvemos a nuestro directorio de partida
cd || exit
# volver_realizar_tarea
}
# ---------------- FIN FUNCION MENU CASE 1 ------------------------------
# ---------------- FUNCION MENU CASE 2 ------------------------------
function menu_case2() {
# declaramos una variable de directorio, atencion con espacios en rutas o nombres de archivo en UNIX (en este caso utilizaremos variable global de entorno)
# si nuestra variable de entrono ($HOME) esta rota, puede que no funcione el programa
# mas informacion en:
# https://wiki.archlinux.org/index.php/environment_variables
dir_cron_list="$HOME/.CrontabAdmin-cycled/"
# controlamos de que el directorio existe
if [ ! -d "$dir_cron_list" ]; then
# si el directorio no existe, lo creamos
mkdir "$dir_cron_list"
# escupimos este mensaje de informacion al usuario en zenity de que no existe el directorio y que se crea uno nuevo
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Se creo el directorio: \\n ${dir_cron_list} \\n para almacenamiento ya que no se encontro"
# mensaje de depuracion
echo "${dir_cron_list} no se encontro este directorio de almacenamiento para el programa, el directorio se ha creado de nuevo"
fi
string_tarea=$(zenity --entry --title="Escribe propiedades de la tarea" --text="Ejemplo:" --entry-text="59 14 * * * /mi/ruta")
# entrada al directorio "$HOME/backups-base-de-datos/" de la variable dri_cron_list, usamos "|| exit" para controlar en caso de que "cd" pueda fallar por falta de permisos, directorios inexistentes o links simbolicos rotos
# exit sirve para abortar inmediatamente
cd "$dir_cron_list" || exit
# por si acaso si existe ya el archivo temporal, lo borramos para evitar conflictos
if [ -e temp-crontab.txt ]; then
rm temp-crontab.txt
fi
# necesitamos guardar tareas ya programadas, ya que cuando pasamos una variable con una tarea introducida por usuario con "crontab miarchivodetareas.txt", simplemente sobreescribe con contenido de "miarchivodetareas.txt" sobre lo que ya esta programado en crontab
cron_texto=$(crontab -l)
# con operador "-z" (z) controlamos que no haya al menos una tarea existente (ya programada)
if [[ -z "$cron_texto" ]]; then
# creamos archivo de texto temporal donde almacenaremos lo que el usuario tecleo en en la variable tarea
touch temp-crontab.txt
# borramos cualquier contenido dentro de archivo de texto temporal y movemos nuestra linea de tarea dentro de archivo de texto temporal (NO OLVIDARSE DE "echo" AL PASAR)
echo "$string_tarea">temp-crontab.txt
# con crontab importamos la linea que contiene la tarea desde nuestro archivo de texto temporal
crontab temp-crontab.txt
# si ya tenemos al menos una tarea
else
# necesitamos correspondiente archivo de texto temporal para almacenar tareas que ya tenemos
# lo creamos si hay al menos una tarea
# creamos archivo de texto temporal donde almacenaremos lo que el usuario tecleo en en la variable tarea
touch temp-crontab.txt
# y le pasamos el contenido de las tareas
echo "$cron_texto">temp-crontab.txt
# borramos cualquier contenido dentro de archivo de texto temporal y movemos nuestra linea de tarea dentro de archivo de texto temporal (NO OLVIDARSE DE "echo" AL PASAR)
echo "$string_tarea">>temp-crontab.txt
# con crontab importamos la linea que contiene la tarea desde nuestro archivo de texto temporal
crontab temp-crontab.txt
fi
# ya no queremos tener archivo temporal asi que lo borramos
rm temp-crontab.txt
# mensajes de depuracion
echo
echo "Se escribio con exito en el crontab la siguiente linea: "
echo "$string_tarea"
# echo "${STRING}" >> /tmp/crontab.*/crontab #ARCHIVO TEMPORAL, NO TOCAR
# volvemos a nuestro directorio de partida, usamos "|| exit" para controlar en caso de que "cd" pueda fallar por falta de permisos, directorios inexistentes o links simbolicos rotos
cd || exit
zenity --width=400 --height=120 --info --window-icon="info" --title="Tarea añadida" --text="Se escribio con exito la siguiente tarea en tu lista de tareas de crontab: \\n\\n${string_tarea}"
volver_realizar_tarea
}
# EXPLICACION DETALLADA DE LA LINEA DE CRON
# * * * * * "comando a ejecutar"
# - - - - -
# | | | | |
# | | | | L----- dia de la semana (de 0 a 7) (Domingo=0 or 7)
# | | | L------- mes (de 1 a 12)
# | | L--------- dia del mes (de 1 a 31)
# | L----------- hora (de 0 a 23)
# L------------- minuto (de 0 a 59)
# ---------------- FIN FUNCION MENU CASE 2 ------------------------------
# ---------------- FUNCION MENU CASE 3 ------------------------------
function menu_case3() {
# almacenamos lo que nos devuelve el comando "crontab -l" que sirve para ver las tareas que ya tenemos programadas
cron_lista_tareas=$(crontab -l)
# si no hay nada dentro de la variable (en este caso si no hay nada en nuestras tareas de crontab), avisamos al usuario
if [[ -z "$cron_lista_tareas" ]]; then
# avisamos al usuario con un mensaje de informacion en zenity de que no tiene ni una tarea programada
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="No tienes ninguna tarea programa"
# si el usuario pulso sobre boton SI, entonces ira al caso 2
if zenity --width=400 --height=120 --question --text="¿Quieres programar una tarea ahora?" --ok-label="Si" --cancel-label="No"; then
# llamamos a la funcion de programacion de tareas automatizadas desde aqui
menu_case2
else
# volvemos al menu principal
volver_realizar_tarea
fi
else
if zenity --width=400 --height=120 --question --text="¿Estas seguro de que quieres borrar todas las tareas programadas?" --ok-label="Si" --cancel-label="No borrar nada"; then
# borramos todas las tareas que tuviesemos ya programadas
crontab -r
# almacenamos lo que nos devuelve el comando "crontab -l" que sirve para ver las tareas que ya tenemos programadas
cron_lista_tareas=$(crontab -l)
# si hay algo dentro de la variable (en este caso si hay algo en nuestra lista de tareas de crontab), avisamos al usuario
if [[ -n "$cron_lista_tareas" ]]; then
# avisamos al usuario con un mensaje de informacion en zenity de que no tiene ni una tarea programada
zenity --width=400 --height=120 --error --title="ERROR" --text "Algo salio mal, no se borro la lista de tareas de crontab, o el archivo de tareas no quedo vacio"
# si el usuario pulso sobre boton SI, entonces ira al caso 2
if zenity --width=400 --height=120 --question --text="¿Desea volver a intentarlo?" --ok-label="Si" --cancel-label="Ir al menu principal"; then
# llamamos a la funcion de nuevo y finalizamos la instancia actual
menu_case3; return
else
# a traver de un mensaje en zenity avisamos al usuario de que limpio exitosamente su lista de tareas programadas
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has limpiado correctamente la lista de tareas"
fi
fi
fi
# a traver d eun mensaje en zenity avisamos al usuario de que limpio exitosamente su lista de tareas programadas
# zenity --width=350 --height=120 --info --window-icon="info" --title="Atencion" --text="Has limpiado correctamente la lista de tareas"
fi
volver_realizar_tarea
}
# ---------------FIN FUNCION MENU CASE 3 ------------------------------
# ---------------FUNCION MENU CASE 4 ------------------------------
function menu_case4() {
# declaramos una variable de directorio, atencion con espacios en rutas o nombres de archivo en UNIX (en este caso utilizaremos variable global de entorno)
# si nuestra variable de entrono ($HOME) esta rota, puede que no funcione el programa
# mas informacion en:
# https://wiki.archlinux.org/index.php/environment_variables
dir_cron_list="$HOME/.CrontabAdmin-cycled/"
# controlamos de que el directorio existe
if [ ! -d "$dir_cron_list" ]; then
# si el directorio no existe, lo creamos
mkdir "$dir_cron_list"
# escupimos este mensaje de informacion al usuario en zenity de que no existe el directorio y que se crea uno nuevo
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Se creo el directorio: \\n ${dir_cron_list} \\n para almacenamiento ya que no se encontro"
# mensaje de depuracion
echo "${dir_cron_list} no se encontro este directorio de almacenamiento para el programa, el directorio se ha creado de nuevo"
fi
# metemos en una variable la ruta del archivo para su posterior comprobacion de que existe
ruta_programa_backup="$HOME/.CrontabAdmin-cycled/backup_trigger.sh"
# de la variable anterior, la imprimimos en terminal como string y con el "cut" recortamos solo el nombre de archivo que dispara el backup con delimitador "-d" marcando como caracter delimitador "/" y indicamos que queremos campo numero 5 con "-f"
comprobacion_archivo_trigger_corto=$(echo "${ruta_programa_backup}" | cut -d/ -f5)
# controlamos de que el archivo existe
if [ ! -f "$ruta_programa_backup" ]; then
# si se da el caso de que el archivo que se encarga de backup de base de datos (necesario para este programa) no existe
# la causa puede ser que el paquete (package) no se instalo correctamente, tambien puede ser que este programa se este usando manualmente sin instalacion, o que el usuario lo borro con permisos de superusuario a proposito
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "El archivo '${comprobacion_archivo_trigger_corto}' no existe\\n\\nLa causa puede ser que el paquete no se instalo correctamente, tambien puede ser que este programa se este usando manualmente sin instalacion, o que el usuario borro el archivo con permisos de superusuario a proposito, con lo cual requiere atencion de administrador del sistema que tenga acceso a superusuario"
# avisamos a traves de zenity con un mensaje de error emergente de que tiene un problema grave
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "Consulte el problema con administrador del sistema"
# volvemos al menu principal, ya que no tiene sentido seguir
volver_realizar_tarea; return
fi
# almacenamos el valor de variable que contiene nombre de usuario, desde nuestro script que dispara el backup, proporcionando la ruta hacia el archivo, cogiendo solo la linea de donde se declara la variable de usuario "usuario_de_bd" y recortando con "cut" solo el valor con la ayuda de delimitador """ y cortando solo el campo numero 2 gracias a "-f"
# almacenamos en una variable, el resultado del comando "cat" que coge nuestro archivo que dispara backup de datos, con "grep" buscamos dentro de el la linea que empieza con "usuario_de_bd=" (que es el claro indicativo de que es una variable), con "cut" recortamos nuestro string que esta entre "" con delimitador "-d" y indicamos que el delimitador sera """ y con "-f" que nos recorte solo el campo numero 2
usuario_actual_trigger=$(cat -n "$HOME"/.CrontabAdmin-cycled/backup_trigger.sh | grep -F "usuario_de_bd=" | cut -d'=' -f2)
# comprobamos que hemos obtenido nombre del usuario de base de datos, si la variable "usuario_de_bd" tiene un nombre diferente, entonces no obtendremos ningun valor sino un string vacio, por lo tanto variable "usuario_actual_trigger" estara vacia
if [[ -z "$usuario_actual_trigger" ]]; then
# avisamos con mensaje en zenity de que no se encontro la variable que estabamos intentando extraer
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "No se encontro la variable 'usuario_de_bd'"
# avisamos a traves de un mensaje en zenity de que el usuario tiene un grave error, de que archivo que dispara el backup esta corrupto o que alguien con acceso a superusuario (contraseña para usuario) modifico el archivo
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "El archivo '${comprobacion_archivo_trigger_corto}' parece estar dañado\\n\\nLa causa puede ser que el paquete no se instalo correctamente, tambien puede ser que este archivo se modifico por alguien que tiene acceso a superusurio del sistema, con lo cual requiere atencion de administrador del sistema que tenga acceso a superusuario"
# recomendamos al usuario de que consulte al administrador
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "Consulte el problema con administrador del sistema"
# volvemos al menu principal, ya que no tiene sentido seguir
volver_realizar_tarea; return
fi
# almacenamos el valor de nombre de base de datos desde nuestro script que dispara el backup, proporcionando la ruta hacia el archivo, cogiendo solo la linea de donde se declara la variable de usuario "nombre_de_bd" y recortando con "cut" solo el valor con la ayuda de delimitador " y cortando solo el campo numero 2
nombre_db_actual_trigger=$(cat -n "$HOME"/.CrontabAdmin-cycled/backup_trigger.sh | grep -F "nombre_de_bd=" | cut -d'=' -f2)
# comprobamos que hemos obtenido nombre del base de datos, si la variable "nombre_de_bd" tiene un nombre diferente, entonces no obtendremos ningun valor sino un string vacio, por lo tanto variable "nombre_db_actual_trigger" estara vacia
if [[ -z "$nombre_db_actual_trigger" ]]; then
# avisamos con mensaje en zenity de que no se encontro la variable que estabamos intentando extraer
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "No se encontro la variable 'nombre_de_bd'"
# avisamos a traves de un mensaje en zenity de que el usuario tiene un grave error, de que archivo que dispara el backup esta corrupto
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "El archivo '${comprobacion_archivo_trigger_corto}' parece estar dañado\\n\\nLa causa puede ser que el paquete no se instalo correctamente, tambien puede ser que este archivo se modifico por alguien que tiene acceso a superusurio del sistema, con lo cual requiere atencion de administrador del sistema que tenga acceso a superusuario"
# recomendamos al usuario de que consulte al administrador
zenity --width=400 --height=120 --error --title="ERROR GRAVE" --text "Consulte el problema con administrador del sistema"
# volvemos al menu principal, ya que no tiene sentido seguir
volver_realizar_tarea; return
fi
# mostramos un mensaje informativo en zenity, con la informacion de valores de variables que tenemos asignadas en el programa que ejecuta backup de nuestra base de datos, nos mostrara los valores de usuario de base de datos y el nombre de base de datos
zenity --width=400 --height=120 --info --window-icon="info" --title="Informacion" --text="Ahora mismo el programa que ejecuta el backup de base de datos tiene siguientes valores: \\n\\n\\n -USUARIO: ${usuario_actual_trigger} \\n\\n -NOMBRE DE BASE DE DATOS: ${nombre_db_actual_trigger}"
# preguntamos al usuario de si quiere cambiar estos datos
if zenity --width=400 --height=120 --question --text="¿Deseas modificar estos datos antes de proceder? \\n\\n\\n -NOMBRE DE USURIO DE BASE DE DATOS\\n\\n -NOMBRE DE BASE DE DATOS" --ok-label="Si" --cancel-label="No"; then
# controlamos de que el demonio de crontab no este ejecutandose, y que no dispare casualmente una tarea programada justo en el momento de edicion de datos que estan en el programa que dispara backups
echo -e "$password" | sudo -S /etc/init.d/cron stop
# en zenity captamos con "entry" la introduccion de datos de usuario
mod_usuario_bd=$(zenity --entry --title="Escribe nombre de usuario de base de datos" --entry-text="postgres")
mod_nombre_bd=$(zenity --entry --title="Escribe nombre de base de datos" --entry-text="tienda")
# modificamos directamente la linea que contiene "usuario_de_bd=" que es justo donde se declara la variable, y ponemos a nuestra nueva linea que se va a llamar igual que la anterior "usuario_de_bd=" y le pasamos valor que introdujo el usuario en justamente comandos anteriores, luego indicamos donde esta nuestro programa que realiza dumps
sed -i "s/usuario_de_bd=.*/usuario_de_bd=${mod_usuario_bd}/g" "$ruta_programa_backup"
# exactamente lo mismo que comando anterior pero con la variable de nombre de base de datos
sed -i "s/nombre_de_bd=.*/nombre_de_bd=${mod_nombre_bd}/g" "$ruta_programa_backup"
# USARIO_DE_BD=$mode_usario_bd ./2.sh
# guys now I need to pass the value of my variable called "mod_usuario_bd" with value "postgres" from "1.sh" into variable called "usuario_de_bd" ("usuario_de_bd="jon"") which is stored in "2.sh"
# notificaremos con un mensaje informativo en zenity que los valores introducidos por el usuario se traspasaron correctamente a las variables de script disparador de backups
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has modificado correctamente los datos"
# volvemos a iniciar demonio de crontab
echo -e "$password" | sudo -S /etc/init.d/cron start
fi
# si tras tanta comprobacion salio todo bien, ejecutamos el script que dispara el backup, y asi obtendremos el tan deseado dump de nuestra tan valiosa, querida y amada base de datos
$ruta_programa_backup
volver_realizar_tarea; return
}
# ---------------- FIN FUNCION MENU CASE 4 ------------------------------
# ------------------ FUNCION MENU CASE 5 ------------------------------
function menu_case5() {
# diferentes distribuciones de sistema operativo GNU/Linux usan diferentes sistemas de inicializacion y administracion de servicios (init system), por lo tanto para mejorar la compatiblidad con cada una vamos a ejecutar algunos comandos para ver con que sistema de inicializacion estamos tratando
# cuando acertemos con el comando adecuado, nos dara alguna salida de datos, mientras otros no daran absolutamente, ya que no estaran isntalados
# hoy en dia las distribuciones mayoritarias usaran el polemico "SystemD", mientras por ejemplo en Gentoo esta adaptado "OpenRC"
# este comando podria valer, pero hay que poner varios con nombres de system-inits correspondientes
# init_upstart=$(ps -eaf|grep '[u]pstart')
# este comando captara string de como se llama nuestro sistema de inicializacion y lo almacenara en una variable, el comando se detendra nada mas encontrar un string que coincide
init_system=$(strings /sbin/init | awk 'match($0, /(upstart|systemd|openrc|sysvinit|runit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }')
# nos vendra muy bien convertir nuestra variable enteramente a minusculas si contiene mayuscuas
a_minusculas=${init_system,,}
# mensaje de depuracion en terminal
echo "***************"
echo "$a_minusculas"
# o podemos usar el siguiente codigo con programa "sed", para pasar a minusculas si el anterior llegase a no funcionar
# a_minusculas="$init_system"
# a_minusculas=$(echo "$a_minusculas" | sed 's/.*/\L&/')
# echo "$a_minusculas"
# pasamos nuestra string a nuestra variable principal
init_system="$a_minusculas"
# mensaje de depuracion para ver que sistema de inicializacion tenemos
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Tienes instalado: \\n\\n ${init_system}"
# ahora solo se ejecutara un "if" si el string de nuestra variable coincide
if [ "$init_system" == systemd ]; then
# echo -e "$password" | sudo -S systemctl restart cron.service
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has reiniciado servicio de cron en ${init_system}"
fi
if [ "$init_system" == openrc ]; then
echo -e "$password" | sudo -S /etc/init.d/cron restart
# esto habilita el servicio (siempre se iniciara automaticamente al iniciar el sistema)
# echo -e "$password" | sudo -S rc-update add cron default
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has reiniciado servicio de cron en ${init_system}"
fi
if [ "$init_system" == upstart ]; then
echo -e "$password" | sudo -S /etc/init.d/cron restart
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has reiniciado servicio de cron en ${init_system}"
fi
if [ "$init_system" == sysvinit ]; then
echo -e "$password" | sudo -S /etc/init.d/cron restart
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has reiniciado servicio de cron en ${init_system}"
fi
if [ "$init_system" == runit ]; then
echo -e "$password" | sudo -S sv restart cron
zenity --width=400 --height=120 --info --window-icon="info" --title="Atencion" --text="Has reiniciado servicio de cron en ${init_system}"
# para habilitar el servicio
# ln -s /etc/sv/cron /var/service/
fi
volver_realizar_tarea; return
}
# ---------------- FIN FUNCION MENU CASE 5 ------------------------------