From 04c4b5c4eb63226c274d836308c9fad53cca31cf Mon Sep 17 00:00:00 2001 From: Emmanuel Date: Thu, 23 Mar 2023 02:34:20 -0300 Subject: [PATCH] Squashed 'command-helper/' content from commit 80c1604 git-subtree-dir: command-helper git-subtree-split: 80c160472e0ddea706d6ac0df2c0a61a8e823971 --- .gitignore | 3 + DOCUMENTATION.org | 746 +++++++++++++++++++++ Makefile | 180 +++++ README.org | 71 ++ config.cfg | 41 ++ doc/applications/commands/.template | 8 + doc/applications/commands/docker.sh | 6 + doc/applications/commands/logseq.sh | 2 + doc/applications/commands/neovim.sh | 14 + doc/applications/commands/qutebrowser.sh | 8 + doc/applications/shortcuts/.template | 11 + doc/applications/shortcuts/logseq.org | 8 + doc/applications/shortcuts/neovim.org | 26 + doc/applications/shortcuts/qutebrowser.org | 44 ++ doc/linux-shell/commands/.template | 8 + doc/linux-shell/commands/amixer.sh | 19 + doc/linux-shell/commands/cal.sh | 21 + doc/linux-shell/commands/column.sh | 19 + doc/linux-shell/commands/curl.sh | 8 + doc/linux-shell/commands/cut.sh | 34 + doc/linux-shell/commands/fish.sh | 2 + doc/linux-shell/commands/ls.sh | 26 + doc/linux-shell/commands/mv.sh | 8 + doc/linux-shell/commands/pgrep.sh | 37 + doc/linux-shell/commands/screen.sh | 14 + doc/linux-shell/commands/sort.sh | 27 + doc/linux-shell/commands/tar.sh | 29 + doc/linux-shell/commands/tee.sh | 36 + doc/linux-shell/commands/timeout.sh | 29 + doc/linux-shell/commands/tr.sh | 61 ++ doc/linux-shell/commands/truncate.sh | 15 + doc/linux-shell/commands/uniq.sh | 45 ++ doc/linux-shell/commands/watch-tail.sh | 8 + doc/linux-shell/commands/whatis.sh | 11 + doc/linux-shell/commands/whiptail.sh | 40 ++ doc/linux-shell/commands/who.sh | 26 + doc/linux-shell/commands/xargs.sh | 21 + doc/linux-shell/shortcuts/.template | 11 + doc/linux-shell/shortcuts/fish.org | 5 + doc/linux-shell/shortcuts/screen.org | 21 + doc/notes/tty-pts.org | 54 ++ scripts/edit-popup.sh | 10 + utils/menus.mk | 81 +++ utils/unix-utils.mk | 24 + utils/update-bash-aliases | 4 + utils/utils.mk | 18 + 46 files changed, 1940 insertions(+) create mode 100644 .gitignore create mode 100644 DOCUMENTATION.org create mode 100644 Makefile create mode 100644 README.org create mode 100644 config.cfg create mode 100644 doc/applications/commands/.template create mode 100644 doc/applications/commands/docker.sh create mode 100644 doc/applications/commands/logseq.sh create mode 100644 doc/applications/commands/neovim.sh create mode 100644 doc/applications/commands/qutebrowser.sh create mode 100644 doc/applications/shortcuts/.template create mode 100644 doc/applications/shortcuts/logseq.org create mode 100644 doc/applications/shortcuts/neovim.org create mode 100644 doc/applications/shortcuts/qutebrowser.org create mode 100644 doc/linux-shell/commands/.template create mode 100644 doc/linux-shell/commands/amixer.sh create mode 100644 doc/linux-shell/commands/cal.sh create mode 100644 doc/linux-shell/commands/column.sh create mode 100644 doc/linux-shell/commands/curl.sh create mode 100644 doc/linux-shell/commands/cut.sh create mode 100644 doc/linux-shell/commands/fish.sh create mode 100644 doc/linux-shell/commands/ls.sh create mode 100644 doc/linux-shell/commands/mv.sh create mode 100644 doc/linux-shell/commands/pgrep.sh create mode 100644 doc/linux-shell/commands/screen.sh create mode 100644 doc/linux-shell/commands/sort.sh create mode 100644 doc/linux-shell/commands/tar.sh create mode 100644 doc/linux-shell/commands/tee.sh create mode 100644 doc/linux-shell/commands/timeout.sh create mode 100644 doc/linux-shell/commands/tr.sh create mode 100644 doc/linux-shell/commands/truncate.sh create mode 100644 doc/linux-shell/commands/uniq.sh create mode 100644 doc/linux-shell/commands/watch-tail.sh create mode 100644 doc/linux-shell/commands/whatis.sh create mode 100644 doc/linux-shell/commands/whiptail.sh create mode 100644 doc/linux-shell/commands/who.sh create mode 100644 doc/linux-shell/commands/xargs.sh create mode 100644 doc/linux-shell/shortcuts/.template create mode 100644 doc/linux-shell/shortcuts/fish.org create mode 100644 doc/linux-shell/shortcuts/screen.org create mode 100644 doc/notes/tty-pts.org create mode 100755 scripts/edit-popup.sh create mode 100644 utils/menus.mk create mode 100644 utils/unix-utils.mk create mode 100755 utils/update-bash-aliases create mode 100644 utils/utils.mk diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1861191 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +applications.txt +linux-shell.txt +notes.txt \ No newline at end of file diff --git a/DOCUMENTATION.org b/DOCUMENTATION.org new file mode 100644 index 0000000..b0f844c --- /dev/null +++ b/DOCUMENTATION.org @@ -0,0 +1,746 @@ +#+TITLE: Documentation +* Intro + #+BEGIN_QUOTE + Centralizamos los comentarios sobre las implementaciones en los Makefiles, + para separar la explicación de la implementación en si + #+END_QUOTE +* Comparación de Timestamp entre Target y sus dependencias + #+BEGIN_SRC makefile + DOC_COMANDOS_LINUX = $(wildcard doc/*.sh) + + # Problemas con éste target: + # + # 1. al utilizar el símbolo ; dentro del foreach se ejecutará en cada iteración + # y al igual que en la terminal de linux, hará que cada comando se ejecute de forma independiente + # + # 2. lo anterior es problema suponiendo que queremos transformar la información generada + # (Ej. agregandole una cabecera) + # + imprimir-comando-descripcion: + $(foreach comando, $(DOC_COMANDOS_LINUX), cat $(comando) | sed -n '1p';) + #+END_SRC + + #+BEGIN_SRC makefile + DOC_COMANDOS_LINUX = $(wildcard doc/*.sh) + + # Problemas con estos targets: + # + # 1. estamos creando un archivo comandos-linux.txt cada vez que ejecutamos imprimir-comandos, + # es decir no comprobamos si se actualizaron ó no los archivos contenidos en $(DOC_COMANDOS_LINUX) + # + # 2. no estamos aprovechando la comparación del timestamp entre el target y las dependencias para crear archivos de GNU Make, + # la manera más común sería una regla como la siguiente.. archivo-transformado.txt: archivo1.txt archivo2.txt archivo3.txt + # + imprimir-comandos: comandos-linux.txt + + comandos-linux.txt: + $(foreach comando, $(DOC_COMANDOS_LINUX), cat $(comando) | sed -n '1p';) + #+END_SRC +* Función Basename + #+BEGIN_SRC makefile + DOC_COMANDOS_LINUX = $(wildcard doc/*.sh) + + # Nota: $(patsubst pattern, replacement, text) + + # Problemas: + # 1. NO era necesario utilizar la función patsubst, sólo necesitabamos usar la función basename de GNU Make + # 2. Si bien le ponemos "WRONG", éste método funciona pero se pierde expresividad y es más dificil de mantener + COMANDOS_LINUX_WRONG = $(notdir $(patsubst %.sh,%,$(DOC_COMANDOS_LINUX))) + + COMANDOS_LINUX = $(basename $(notdir $(DOC_COMANDOS_LINUX))) + #+END_SRC +* Función filter-out + #+BEGIN_SRC makefile + DOC_COMANDOS_LINUX = $(wildcard doc/*.sh) + DOC_SHORTCUTS_LINUX = $(wildcard doc/*.org) + + # Nota: $(filter-out pattern, text) + # + # 1. Filtramos de (A) los elementos (a) que no estén incluidos en otra lista (B) + # + COMANDOS_LINUX_WITHOUT_SHORTCUTS = $(filter-out $(SHORTCUTS_LINUX),$(COMANDOS_LINUX)) + #+END_SRC +* Comando bat +** Problema al ejecutar + #+BEGIN_QUOTE + *Posible Problema:* + - al ejecutar el binario el emulador de terminal diga ~Command 'bat' not found~ + + *Solución:* + - crear un softlink de ~/usr/bin/batcat~ en ~~/.local/bin/bat~ + #+END_QUOTE + +#+BEGIN_SRC shell + # suponiendo que no existe el directorio + mkdir -p ~/.local/bin + + # creamos el softlink /usr/bin/batcat en ~/.local/bin/bat + ln -s /usr/bin/batcat ~/.local/bin/bat +#+END_SRC +** Referencias +*** Referencias Extraoficiales + 1. [[https://www.makeuseof.com/bat-an-alternative-to-cat-command/][bat an alternative to cat omcmand (makeuseof.com)]] +*** Referencias Issues + 1. [[https://github.com/sharkdp/bat/issues/1420#issuecomment-737058971][Bat doesn't work when installed from apt on ubuntu (github.com/sharkdp/bat)]] +* Macro Expansiva Vs Macro Simple - Evaluación y Expansión de Macro con comando shell +** Problemas + #+BEGIN_QUOTE + Según la que eligamos dará *problemas ó no cuando les asignamos un comando de shell*.. + + Si es una *MACRO RECURSIVA*, entonces utilizamos el símbolo de asignación ~=~ + Por ejemplo ~archivo-especifico = $(shell ls *.md | grep '^READ')~ + - PROBLEMA 1: GNU Make lo evaluará y expandirá cada vez que se referencie en el Makefile + - PROBLEMA 2: ejecuta el comando a cada rato, en lugares dónde aún no queríamos que se ejecutara (Ej. en un ifeq) + + Si es una *MACRO SIMPLE*, entonces utilizamos el símbolo de asignación ~:=~ + - Por ejemplo ~archivo-especifico := $(shell ls *.org | grep 'TODO\.org$')~ + - PROBLEMA 1: GNU Make lo evaluará varias veces pero se expandirá una única vez (la primera vez que se referenció) + - PROBLEMA 2: ejecutará apenas ejecutamos el Makefile (peor que antes) + #+END_QUOTE + + #+BEGIN_SRC makefile + # a diferencia de las alternativas de abajo, ésta si funciona y evitamos los problemas de expansión no deseada de GNU Make + POPUP_EDIT = sh ./scripts/edit-popup.sh + + # Notas: + # - en todas las siguientes asignaciones causarán problemas cuando GNU Make las evalué y expanda + # - de igual forma las comento por el tema de que cada linea en una regla de Makefile se ejecuta en una shell diferente + + # 1. alternativa a la función shell sería usando el símbolo != + # 2. en éste ejemplo considero que queda mejor usar shell para no confundir y no olvidar que el comando read es propio de linux + POPUP_EDIT != read -p "Si desea editar comandos escriba sin paréntesis (c) y para shortcuts (s): " popup_edit; echo $$popup_edit + + # + # 1. nuestro comando shell imprimirá un string que se asignará a la macro POPUP_EDIT + # 2. los comandos de linux se ejecutarán en la misma shell, por tanto se perderá el valor si intentamos imprimir $$popup_edit en otra macro ó target + POPUP_EDIT ?= $(shell read -p "Desea editar comandos escriba (c) para shortcuts (s): " popup_edit; echo $$popup_edit) + + # 1. también sólo podriamos asignar los comandos a ejecutar como un string + # 2. para no perder el valor de popup_edit podríamos utilizar el operador && para manternos en la misma shell así $(POPUP_EDIT) && echo $$popup_edit + # pero... no podriamos utilizarlo en un ifeq de GNU Make + POPUP_EDIT = read -p "Si desea editar comandos escriba sin paréntesis (c) y para shortcuts (s): " popup_edit; echo $$popup_edit + #+END_SRC +** Referencias +*** Referencias Extraoficiales + 1. [[https://make.mad-scientist.net/deferred-simple-variable-expansion/][Deferred simple variable expansion (make-mad-scientist.net)]] + 2. [[https://seanbone.ch/makefile-hacks/][Makefile hacks (seanbone.ch)]] +*** Referencias Issues + 1. [[https://nono.ma/prompt-user-input-makefile][Prompt user input makefile (nono.ma)]] + 2. [[https://stackoverflow.com/questions/3743793/makefile-why-is-the-read-command-not-reading-the-user-input][makefile why is the read command not reading the user input (stackoverflow.com)]] + 3. [[https://unix.stackexchange.com/questions/31414/how-can-i-pass-a-command-line-argument-into-a-shell-script][How can I pass a command line argument into a shell script (unix.stackexchange.com)]] + 4. [[https://stackoverflow.com/questions/32153034/oneshell-not-working-properly-in-makefile][Oneshell not working properly in makefile (stackoverflow.com)]] +* Condicionales Simples de Bash +** Problemas + #+BEGIN_QUOTE + Podemos usar el comando ~test -f archivo~ para verificar si existe con los operadores lógicos ~&&~ y ~||~ + - la expresión seguida del operador lógico AND ~&&~ se evalúa si existe el archivo + - la expresión seguida del operador lógico OR ~||~ se evalúa si NO existe el archivo + + ó podemos usar el condicional ~if [ -s archivo ]~ sin olvidar el uso de los ~;~ + - usar ~;~ al final de cada expresión delimitada dentro de la condición ~if~ ó del ~else~ + - finalizar el bloque ~if~ con un ~fi~ + #+END_QUOTE + + #+BEGIN_SRC makefile + doc/archivo.txt: .tmp/archivo-4.txt .tmp/archivo-1.txt .tmp/archivo-9.txt + @test -f $@ \ + && echo "existe el archivo..!" \ + || echo "no existe el archivo, ejecutar algún comando que procese los archivos dependencia y cree el archivo" + + doc/otro-archivo.txt: .tmp/archivo-1.txt .tmp/archivo-2.txt .tmp/archivo-3.txt + @if [ -s $@ ]; then \ + echo "existe el archivo"; \ + else \ + echo "no existe el archivo, ejecutar algún comando que procese los archivos dependencia y cree el archivo"; \ + fi + #+END_SRC +** Referencias +*** Referencias Issues + 1. [[https://stackoverflow.com/questions/5553352/how-do-i-check-if-file-exists-in-makefile-so-i-can-delete-it][How do I check if file exists in makefile (stackoverflow.com)]] + 2. [[https://stackoverflow.com/questions/8059556/how-to-write-multiple-conditions-in-makefile-am-with-else-if][How to write multiple conditions in makefile (stackoverflow.com)]] +* Comandos awk + sed - Expresiones Regulares +** Ejemplo Básico + #+BEGIN_QUOTE + Generamos un archivo ~comandos-linux.txt~ en base al contenido de sus dependencias (los .sh) + - siempre que en una regla de Makefile haya una diferencia en el *timestamp* entre el TARGET y sus DEPENDENCIAS + - con la diferencia de timestamp, GNU Make nos permitirá ejecutar la orden asociada a la creación del TARGET + - creamos el archivo (target) cuando los archivos de los que depende (sus dependencias) tienen una fecha de modificación más reciente + #+END_QUOTE + + #+BEGIN_SRC makefile + # - truncamos el archivo, lo modificamos el tamaño del archivo a cero Bytes + # - todos los datos que tenía se pierden + archivo.txt: + @truncate -s 0 $@ + + # - iteramos sobre cada dependencia del target + # - la macro especial $^ obtiene todas las dependencias + # - la función foreach es de la forma (foreach elemento-de-la-lista, lista-de-archivos, orden-a-ejecutar) + # - para utilizar el elemento de la iteración del foreach dentro de la orden que ejecuta, debemos hacerlo como una macro $(elemento-de-la-lista) + @$(foreach comando, $^, echo $(comando)) + + # obtenemos una linea en particular del archivo (la descripción, en la primera linea) + cat archivo.txt | sed -n '1p' + + # agregamos un string al principio de cada linea + cat archivo.txt | nawk '{print "$(basename $(notdir $(comando))) " $$0}' + + # - reemplazamos los símbolos no deseados por ejemplo ~#~ por otro por ej. el pipe ~|~ + # - escapamos los símbolos usando el slash invertido + cat archivo.txt | sed 's/\#/\|/g' + + # - agregamos el texto transformado en el target (el archivo comandos-linux.txt) + # - el operador de redirección ~>>~ que agrega contenido (si usaramos ~>~ borraría el contenido anterior) + # - la macro especial ~$@~ que obtiene el nombre del target + archivo.txt: + echo "texto transformado" >> $@ + #+END_SRC + + #+BEGIN_SRC makefile + comandos-linux.txt: doc/ls.sh doc/mv.sh doc/tar.sh doc/curl.sh + @$(TRUNCATE_CLEAR_CONTENT) $@ + @$(foreach comando, $^,\ + cat $(comando) | sed -n '1p' | nawk '{print "$(basename $(notdir $(comando))) " $$0}' | sed 's/\#/\|/g' \ + >> $@;\ + ) + #+END_SRC +** Ejemplo + #+BEGIN_SRC makefile + comandos-linux.txt: doc/ls.sh doc/mv.sh doc/tar.sh doc/curl.sh + @$(TRUNCATE_CLEAR_CONTENT) $@ + @$(foreach comando, $^,\ + cat $(comando) | \ + sed -n '1,2p' | \ + nawk 'BEGIN{print "$(basename $(notdir $(comando)))|" } {print $$0}' | \ + sed -E 's/\#\# (CATEGORIA)\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2\|/g' | \ + sed -E 's/\#\# (DESCRIPCION)\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2;/g' | \ + tr --delete '\n' | tr ';' '\n' | \ + nawk -F '|' '{print $$1 " | " toupper($$2) " | " toupper(substr($$3,1,1)) substr($$3,2)}' \ + >> $@;\ + ) + #+END_SRC + + #+BEGIN_SRC makefile + # extraemos sólo las lineas 1 y 2 del archivo + cat archivo.txt | sed -n '1,2p' + + # - agregamos al principio de cada linea un texto, en éste caso la macro comando + # - la función notdir obtiene el nombre del archivo (con la extensión, usaremos basename para removerla) + # - la función basename obtiene el nombre del archivo sin la extensión + # - usamos $$0 en vez de $0 para que GNU Make no la tome como una macro de Makefile si que la escape é interprete un caracter y sea un parámetro del comando awk + cat archivo.txt | nawk 'BEGIN{print "$(basename $(notdir $(comando)))|" } {print $$0}' + + # - en las regex es típico usar paréntesis para los Grupos de Captura (Capture Group) es decir son "Construcciones de Agrupamiento de Expresiones Regulares" + # - en awk obtenemos el contenido de los Grupos de Captura con \1 \2 .. \n siendo n el número del grupo de captura del que queremos el contenido + cat archivo.txt | sed -E 's/\#\# (CATEGORIA)\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2\|/g' + + # - al final de cada columna de awk le agregamos un símbolo ; como centinela para detectar el fin de linea + cat archivo.txt | sed -E 's/\#\# (DESCRIPCION)\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2;/g' + + # borramos los saltos de linea + cat archivo.txt | tr --delete '\n' + + # reemplazamos los ; por saltos de linea (antes los habíamos agregado para diferenciar el fin de linea) + cat archivo.txt | tr ';' '\n' + + # - indicamos que el separador de las columnas en el símbolo | (el pipe) + # - transformamos el texto manipulando el orden de las columnas $1 $2 $3 detectadas por awk + # (recordando que agregamos un $ al principio $$1 $$2 .. porque si nó GNU Make lo tomará como una macro, y queremos que lo tome como un caracter) + cat archivo.txt | nawk -F '|' '{print $$1 " | " toupper($$2) " | " toupper(substr($$3,1,1)) substr($$3,2)}' + #+END_SRC +** Referencias +*** Referencias Oficiales + 1. [[https://learn.microsoft.com/es-es/dotnet/standard/base-types/grouping-constructs-in-regular-expressions][Construcciones de agrupamiento en expresiones regulares (learn.mirosoft.com)]] +*** Referencias Extraoficiales + 1. [[http://w3.unpocodetodo.info/utiles/regex-en-javascript.php][Grupos de captura en JavaScript (w3.unpocodetodo.info)]] + 2. [[https://bioinf.comav.upv.es/courses/unix/expresiones_regulares.html][POSIX, Cuantificadores, Puntos de anclaje, Sustituciones, Escape de Caracteres (bioinf.comav.upv.es)]] + 3. [[https://www.linuxteck.com/sed-commands-in-linux/][sed commands in linux (linuxteck.com)]] +*** Referencias Issues + 1. [[https://stackoverflow.com/questions/63952656/using-awk-to-set-first-character-to-lowercase-unix][using awk to set first character to lowercase unix (stackoverflow.com)]] + 2. [[https://stackoverflow.com/questions/2609552/how-can-i-use-as-an-awk-field-separator][how can I use as an awk field separator (stackoverflow.com)]] + 3. [[https://stackoverflow.com/questions/1251999/how-can-i-replace-each-newline-n-with-a-space-using-sed][how can I replace each newline n with a space using sed command (stackoverflow.com)]] + 4. [[https://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-in-regular-expressions][what is a non capturing group in regular expressions (stackoverflow.com)]] + 5. [[https://superuser.com/questions/112834/how-to-match-whitespace-in-sed][how to match whitespace in sed command (superuser.com)]] +* Comandos xargs y whiptail + Llamado recursivo a un Makefile +** Posibles Escenarios +*** Escenario (1) con GNU Make + #+BEGIN_QUOTE + 1) Interactuamos con el usuario mediante un cuadro de diálogo + 2) Usaremos el programa ~whiptail~ para la interfáz del cuadro de diálogo + 3) Redireccionamos el stderr al stdout para capturar lo que escribe ~whiptail~ + 4) Capturamos el valor de salida de ~whiptail~ con ~xargs~ para crear nuevos archivos a partir de otros (templates) + #+END_QUOTE + + #+BEGIN_SRC makefile + # alternativa al `rsync --ignore-existing` sería `cp --no-clobber` + COPY_NOT_OVERWRITE=rsync --ignore-existing + + DOC_COMMANDS_LINUX_DIRECTORY=doc/linux-shell/commands + DOC_SHORTCUTS_LINUX_DIRECTORY=doc/linux-shell/shortcuts + + MENU_CREATE_DOC_LINUX= whiptail \ + --inputbox "Escriba el nombre del comando" 25 80 \ + --title "Crear Documentación de Linux" + + linux-create-doc: + $(MENU_CREATE_DOC_LINUX) 3>&1 1>&2 2>&3 \ + | xargs -I % sh -c "\ + $(COPY_NOT_OVERWRITE) $(DOC_COMMANDS_LINUX_DIRECTORY)/.template $(DOC_COMMANDS_LINUX_DIRECTORY)/%.sh; \ + $(COPY_NOT_OVERWRITE) $(DOC_SHORTCUTS_LINUX_DIRECTORY)/.template $(DOC_SHORTCUTS_LINUX_DIRECTORY)/%.org; \ + echo 'Se creó el archivo $(DOC_COMMANDS_LINUX_DIRECTORY)/%.sh;' \ + echo 'Se creó el archivo $(DOC_SHORTCUTS_LINUX_DIRECTORY)/%.org'; \ + " + #+END_SRC +*** Escenario (2) con GNU Make - Makefile recursivo + #+BEGIN_QUOTE + 1) Capturamos la opción elegida del menu de ~whiptail~ con ~xargs~ + 2) La *opción capturada* será el nombre del ~target~ que pasaremos por parámetro al mismo ~Makefile~ para ejecutar + 3) Con ~$(MAKE)~ se invoca a si mismo el Makefile + #+END_QUOTE + + #+BEGIN_SRC makefile + # Notas: + # 1. es necesario definir los targets linux-create-doc y app-create-doc + # 2. al confirmarle a whiptail una opción, la enviará al stdout (file descriptor 1, la pantalla) + # y GNU Make interpretará que el resultado es el nombre de un target + # (si no existen esos targets GNU Make lanzará un error de que deben definirse en el Makefile) + MENU_CREATE_DOC=whiptail \ + --title "Crear documentación" \ + --menu "Elegir una opción" 30 80 5 \ + "linux-create-doc" "Documentación de Linux" \ + "app-create-doc" "Documentación de una Aplicación" + + create-doc: + $(MENU_CREATE_DOC) 3>&1 1>&2 2>&3 \ + | xargs -I % $(MAKE) --no-print-directory % + #+END_SRC +*** Escenario Alternativo - Usando comando read + #+BEGIN_SRC makefile + linux-create-doc: + read -p "Nombre del Comando de Linux a documentar: " NOMBRE \ + && echo $(DOC_COMMANDS_LINUX_DIRECTORY)/$$NOMBRE.$(DOC_COMMANDS_EXTENSION) \ + && echo $(DOC_SHORTCUTS_LINUX_DIRECTORY)/$$NOMBRE.$(DOC_SHORTCUTS_EXTENSION) + + # otra alternativa + linux-create-doc: + printf "Nombre del Comando de Linux a documentar: " && read NOMBRE \ + && echo $(DOC_COMMANDS_LINUX_DIRECTORY)/$$NOMBRE.$(DOC_COMMANDS_EXTENSION) \ + && echo $(DOC_SHORTCUTS_LINUX_DIRECTORY)/$$NOMBRE.$(DOC_SHORTCUTS_EXTENSION) + #+END_SRC +** Comando xargs - Mismo parámetro a múltiples comandos + #+BEGIN_QUOTE + El comando ~xargs~ requiere utilizarlo la forma ~xargs -I % sh -c 'comando1 %; comando2 %; ..'~ + cuando queremos pasar el mismo parámetro ~%~ a multiples comandos en la misma Shell + + El símbolo ~%~ que usamos en los nombres de los ficheros, es el parámetro capturado por el comando ~xargs~ con la opción ~-I~ + #+END_QUOTE +** Comando whiptail - Redirección entre File Descriptors +*** Problema + - el comando ~whiptail~ por defecto escribe sobre el ~stderr~ (fd 2) + - necesitamos redireccionar el ~stderr~ (fd 2) al ~stdout~ (fd 1) +*** Solución 1 - Utilizar la terminal activa /dev/tty + - utilizar el operador de redirección ~>~ de la forma ~file descriptor>&otro fd~ + - redireccionar STDERR a STDOUT y luego STDOUT a la terminal activa (la que está en uso) + + #+BEGIN_QUOTE + Planteandolo quedaría ~2>&1 > /dev/tty~ + 1) ~2>&1~ redireccionamos el STDERR (file descriptor 2) a STDOUT (file descriptor 1) + 2) ~> /dev/tty~ redireccionamos el STDOUT a la terminal activa (la que está en uso) + #+END_QUOTE +*** Solución 2 - Crear nuevo file descriptor + - utilizar el operador de redirección ~>~ de la forma ~file descriptor>&otro fd~ + - crear un *File Descriptor* adicional que guarde la referencia del stdout + + #+BEGIN_QUOTE + Planteandolo quedaría ~3>&1 1>&2 2>&3~ + 1) ~3>&1~ creamos un nuevo File Descriptor (fd 3) que guarda la referencia del stdout (fd 1) + 2) ~1>&2~ redireccionamos el stdout->stderr + 3) ~2>&3~ redireccionamos el stderr->nuevo file descriptor (fd 3, el que apuntaba al stdout) + #+END_QUOTE +** Referencias +*** Referencias Extraoficiales + 1) [[https://phoenixnap.com/kb/xargs-command][xargs Command examples (phoenixnap.com)]] +* Comandos read y whiptail - Redirección de la Terminal activa /dev/tty +** Formas de Redirección utilizadas +*** Operador Pipe (|) + - *redirecciona el STDOUT* como STDIN de otro comando + - ejemplo ~ls *.txt | grep ^b~ (listar todos los archivos de texto plano que empiecen con la letra b) +*** Operador (<) + - *redirecciona el contenido de un archivo* como STDIN de un comando + - ejemplo ~tr 'a-z' 'A-Z' < alumnos.txt~ (convertimos todos caracteres en mayúsculas) + + #+BEGIN_QUOTE + En el posible escenario (1) planteado, que combinamos los comandos ~whiptail~ y ~read~ + - Redireccionamos el *contenido de la terminal en uso* (activa) ~/dev/tty~ con el operador de redirección ~<~ + - ES FUNDAMENTAL la redirección ~< /dev/tty~ caso contrario.. el comando ~read~ FALLARÁ.. + #+END_QUOTE +** Posibles Escenarios +*** Escenario (1) con GNU Make - Comando read + #+BEGIN_QUOTE + Primero la interacción con ~whiptail~ (no es el tema de interés al menos en éste escenario) + 1) Utilizamos ~whiptail~ para mostrar una caja de dialogo + 2) Redireccionamos los *File Descriptor* (STDERR -> STDOUT) para + - porque por default escriben en el *STDERR* (fd 2) + - utilizar la salida de ~whiptail~ como entrada de otro comando con el operador pipe ~|~ + - pasar por parámetro el resultado de ~whiptail~ al propio ~Makefile~ con el comando ~xargs~ + - el parámetro recibido por el ~Makefile~, lo interpeta *GNU Make* como el nombre de un target (que debe estar definido en el Makefile) + 3) Elegida una opción de ~whiptail~, la llamada recursiva ~$(MAKE)~ recibe el nombre del target pasado por parámetro por ~xargs~ + #+END_QUOTE + + #+BEGIN_QUOTE + Segundo la interacción con el comando ~read~ y el operador de redireccion ~<~ (éste era el tema de interés) + 1) Solicitamos por *STDIN* (fd 0) que ingrese el nombre del comando ó aplicación con el comando ~read~ + 2) Redireccionamos el *contenido de la terminal en uso* (activa) ~/dev/tty~ con el operador de redirección ~<~ + #+END_QUOTE + + #+BEGIN_SRC makefile + MENU_CREATE_DOC=whiptail \ + --title "Crear documentación" \ + --menu "Elegir una opción" 30 80 5 \ + "linux-create-doc" "Documentación de Linux" \ + "app-create-doc" "Documentación de una Aplicación" + + # No es necesario utilizar la opción -I, la utilizamos para asignarle un símbolo al parámetro que recibe xargs (el %) + # y que se entienda que se lo estamos pasando por parámetro al llamado recursivo $(MAKE) + create-doc: + $(MENU_CREATE_DOC) 2>&1 > /dev/tty \ + | xargs $(MAKE) --no-print-directory + + # alternativa al 2>&1 >/dev/tty + # create-doc: + # $(MENU_CREATE_DOC) 3>&1 1>&2 2>&3 \ + # | xargs -I % $(MAKE) --no-print-directory % + + # Notas: + # 1. Una alternativa a ~read -p "texto" VARIABLE~ sería ~echo "texto: " && read VARIABLE~ + linux-create-doc: + read -p "Nombre del Comando de Linux a documentar: " NOMBRE < /dev/tty \ + && $(TEXT_EDITOR) $$NOMBRE.sh + + app-create-doc: + read -p "Nombre de la Aplicación a documentar: " NOMBRE < /dev/tty \ + && $(TEXT_EDITOR) $$NOMBRE.org + + .PHONY: create-doc linux-create-doc app-create-doc + #+END_SRC +*** Escenario (2) con GNU Make - Comando whiptail con cuadro de dialogo + #+BEGIN_SRC makefile + LINUX_COMMANDS_LIST=ls ps find tee + LINUX_SHORTCUTS_LIST=neovim screen + + MENU_EDIT_LINUX_COMMANDS=whiptail \ + --title "Editar documentación de Linux" \ + --menu "Elegir una opción" 0 0 5 $(LINUX_COMMANDS_LIST) + + MENU_EDIT_LINUX_SHORTCUTS=whiptail \ + --title "Editar documentación de Linux" \ + --menu "Elegir una opción" 0 0 5 $(LINUX_SHORTCUTS_LIST) + + linux-edit-commands: linux-shell.txt + $(MENU_EDIT_LINUX_COMMANDS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_COMMANDS_LINUX_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION) + + linux-edit-shortcuts: + $(MENU_EDIT_LINUX_SHORTCUTS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_COMMANDS_LINUX_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION) + #+END_SRC +** Referencias +*** Referencias Extraoficiales + 1. [[https://www.baeldung.com/linux/monitor-keyboard-drivers][Difference between /dev/tty and /dev/tty0 (baeldung.com)]] + 2. [[https://linuxhandbook.com/redirection-linux/][Explained: input, output and error redirection in linux (linuxhandbook.com)]] + 3. [[https://linuxhandbook.com/read-command/][Practical examples of the read command in Linux (linuxhandbook.com)]] +*** Referencias Issues + 1. [[https://unix.stackexchange.com/questions/229530/how-linux-uses-dev-tty-and-dev-tty0][How linux uses dev/tty and dev/tty0 (unix.stackexchange.com)]] + 2. [[Https://stackoverflow.com/questions/39631144/why-command-read-doesnt-work][Why command read doesn't work (stackoverflow.com)]] + 3. [[https://stackoverflow.com/questions/6674327/redirect-all-output-to-file-in-bash/6674383#6674383][Redirect all output to file in bash (stackoverflow.com)]] + 4. [[https://stackoverflow.com/questions/1562666/bash-scripts-whiptail-file-select][Bash scripts whiptail file select (stackoverflow.com)]] +* GNU Make - Pasar parámetros sin valor asociado con MAKECMDGOALS y filter +** Problema + #+BEGIN_QUOTE + 1) Queremos pasar un parámetro a un target sin asignarle un valor + 2) Ejecutar en la terminal de comandos ~make mkdir editar~ en vez de ~make editar-comando=mkdir~ + #+END_QUOTE +** Solución + #+BEGIN_SRC makefile + DOC_COMMANDS_LINUX_DIRECTORY=doc/linux-shell/commands + TEXT_EDITOR=vim + + # necesario para poder usar la palabra `edit` como parámetro de cualquier target + $(eval edit:;@:) + + $(COMANDOS_LINUX): + # 1. validamos si pasó el parámetro "edit" en la terminal de comandos, al ejecutar make instanciando un target incluido la macro $(COMANDOS_LINUX) + ifeq (edit, $(filter edit,$(MAKECMDGOALS))) + # 1.1 abrimos el archivo en modo de edición con algún programa (Ej. vim, nano, ..) + $(TEXT_EDITOR) $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.sh + # 1.2 flujo alternativo, si no pasó el parámetro "edit", + # entonces sólo imprimimos el contenido del archivo + else + cat $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.sh + endif + + @test -f $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.sh \ + && cat $(TEXT_EDITOR) $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.sh + || true + #+END_SRC +** Comandos utilizados +*** Comando test + - lo usamos ara *validar existencia de archivos* + - utilizado de la forma ~test -f archivo.txt && echo "existe" || echo "no existe"~ +* GNU Make - Macro con comandos de Shell y utilizada como parámetro a otra función Shell +** Problema + #+BEGIN_QUOTE + 1) Transformar el texto de un target (en este ej. es ~SHORTCUTS_LINUX~) + 2) Agregar saltos de linea (el caracter especial ~\n~) con el comando de linux ~sed~, porque las *funciones de sustitución de GNU Make* no lo hacen + 3) *Pasar por parámetro la macro* con el texto transformado con ~sed~ al comando linux ~awk~ para *filtrar contenido de un archivo* de texto plano + #+END_QUOTE +** Sugerencias + #+BEGIN_QUOTE + Si usamos una ~Macro (A)~ que transforma e imprime el texto de otra ~Macro (B)~, + y esa la ~Macro (A)~ la utilizamos como un comando dentro de una regla para crear un Target/Objetivo, + entonces *GNU Make* buscará en el Makefile los targets con esos nombres.. + + Si ese no era nuestra meta y no habíamos definido targets con esos nombres, + entonces *GNU Make* FALLARÁ diciendo que *NO encontró los targets* para crear el target principal (dónde se incluyó la macro) + + En este ejemplo utilizamos la ~Macro (A)~ como parámetro de un comando de linux + #+END_QUOTE +** Solución + #+BEGIN_SRC makefile + DOC_COMMANDS_LINUX_DIRECTORY=doc/linux-shell/commands + DOC_SHORTCUTS_LINUX = $(wildcard $(DOC_SHORTCUTS_LINUX_DIRECTORY)/*.org) + SHORTCUTS_LINUX = $(basename $(notdir $(DOC_SHORTCUTS_LINUX))) + + # Notas: + # 1. formateamos la lista de palabras, reemplazando los espacios por el pipe | como separador + # 2. permite controlar el contenido del archivo con el comando de linux AWK + SHORTCUTS_LINUX_FORMAT=$(shell echo $(SHORTCUTS_LINUX) | sed -E 's/([[:alpha:]]+) /\1|/g') + + # Notas: + # 1. si usamos el operador != en vez de la función $(shell ) no cumplía su propósito el slash invertido + # 2. en véz de borrar lineas con el comando sed y su opción /d, se prefirió filtrar filas con awk que también permite patrones (más fácil) + LINUX_SHORTCUTS_LIST=$(shell cat commands-linux-shell.txt \ + | awk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/([[:alpha:]]+)::(.+)/\"\1\" \"\2\"\\/g' \ + | awk '/$(SHORTCUTS_LINUX_FORMAT)/' \ + | tr '\\' '\n') + #+END_SRC +** Soluciones fallidas + #+BEGIN_SRC makefile + # el comando `tr` no cumplía su propósito a diferencia del comando `sed` + SHORTCUTS_LINUX_FORMAT_FAIL = $(shell echo $(SHORTCUTS_LINUX) | tr '[:space:]' '\|') + + # el operador de redirección <<< falla + SHORTCUTS_LINUX_FORMAT_FAIL = sed -E 's/([[:alpha:]]+) /\1|/g' <<< "$(SHORTCUTS_LINUX)" + + # ésta fue la macro utilizada, que no arroja errores + SHORTCUTS_LINUX_FORMAT=$(shell echo $(SHORTCUTS_LINUX) | sed -E 's/([[:alpha:]]+) /\1|/g') + #+END_SRC +* GNU Make - Macro con comandos de Shell (awk + sed + tr) +** Objetivo + - Adaptar el texto de un archivo que está de la forma ~dato1|dato2|~ a algo como ~"dato1" "dato2"~ seguidos de un salto de linea ~\n~ + - Crear un menú con el comando ~whiptail --menu~ con el texto transformado +** Problema + 1) Leer el contenido de un archivo de texto plano (.txt) que tiene columnas delimitadas por el símbolo pipe ~|~ + 2) Cambiar el separador de columnas ~|~ por otro ~::~ con ~awk~ para facilitar la sustitución con ~sed~ + 3) Sustituir los textos de las columnas separadas por ~::~ de la forma ~"palabra" "otra"~ seguido de un slash invertido ~\~ + 4) Agregar saltos de linea al final de cada columna +** Solución + #+BEGIN_QUOTE + - si utilizamos ~!/patron/~ en ~awk~, filtramos el contenido de un archivo, usando el ~!~ como una negación ~NOT~ + - la solución actual con ~sed~ se complicaba el borrar lineas con varios patrones) + #+END_QUOTE + + #+BEGIN_SRC makefile + # faltan algunas macros, NO se agregaron enfocar ésta solución + DOC_LINUX=linux-shell + + LINUX_COMMANDS_LIST=$(shell cat $(DOC_LINUX).txt \ + | nawk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/(.+)::(.+)/"\1" "\2" \\/g' \ + | tr '\\' '\n') + + # Nota: Si usamos el operador != en vez de la función $(shell ) no cumplirá su propósito el slash invertido + LINUX_SHORTCUTS_LIST=$(shell cat $(DOC_LINUX).txt \ + | awk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/([[:alpha:]]+)::(.+)/\"\1\" \"\2\"\\/g' \ + | awk '/$(SHORTCUTS_LINUX_FORMAT)/' \ + | tr '\\' '\n') + #+END_SRC +** Referencias +*** Referencias Extraoficiales + 1. [[https://www.baeldung.com/linux/delete-lines-containing-string-from-file][Delete lines containing string from file (baeldung.com)]] + 2. [[https://phoenixnap.com/kb/awk-command-in-linux][awk command in linux (phoenixnap.com)]] +*** Referencias Issues + 1. [[https://unix.stackexchange.com/questions/318839/awk-negative-regular-expression][awk negative regular expression (unix.stackexchange.com)]] +* TODO Shell - Insertar texto en archivos con el Operador de redireccion (>>) + comandos tee y sed +** Problema + #+BEGIN_QUOTE + Existe un problema en las soluciones planteadas con el operador de redirección ~>>~ y de los comandos ~tee~ y ~sed~ + 1) si la última linea del archivo dónde insertarmos contenido no tiene el caracter especial ~\n~ de salto de linea + 2) al insertar contenido en el archivo, éste agregará delante del texto que ya contenía.. en vez de una nueva linea + 3) el resultado de inserción no será el deseado, por tanto "se insertará mal" + #+END_QUOTE +** Operador de redirección (>>) + - con ~echo "texto" >> archivo.txt~ agregamos contenido a un archivo + - si utilizaramos el operador de redirección ~>~ en vez de ~>>~, se borraría el contenido anterior del archivo +** Comando tee + - con ~echo "texto" | tee --append archivo.txt~ agregamos contenido a un archivo + - el comando ~tee~ se diferencia de los operadores de redirección ~>~ y ~>>~ porque + 1) escribe en un archivo + 2) imprime por pantalla (stdout, fd 1) lo que escribió en el archivo +** Comando sed + - con sed es ~sed -i '$ a texto' archivo~ agregamos contenido a un archivo +* GNU Make - Problemas de Condicionales ifeq con comandos de Shell (whiptail) +** Solución fallida (1) +*** Código de la Solución fallida + #+BEGIN_SRC makefile + CONFIRM_INSTALL=$(shell whiptail \ + --title "Instalar Aplicación $(APP_NAME)" \ + --yesno "¿Desea confirmar acción?" 0 0 \ + --no-button "Cancelar" --yes-button "Confirmar" 3>&1 1>&2 2>&3 && echo true) + + # - éste target está MAL, porque la expresión que comparamos CONFIRM_INSTALL escribe un cuadro de diálogo sobre la pantalla (stdout, fd 1) + # - el comando whiptail no devuelve un valor booleano, devuelve la interfáz de un cuadro de dialogo + install: + ifeq ($(CONFIRM_INSTALL), true) + @echo "instalando..." + else + @echo "no hago nada" + endif + #+END_SRC +*** Problema de la solución + #+BEGIN_QUOTE + Si en la terminal de comandos escribimos ~make~ ó ~make nombre-de-algun-target~ + - se va a evaluar cada expresión de la condición del ~ifeq~ de GNU Make + - la macro ~CONFIRM_INSTALL~ se evaluará y se imprime la caja de diálogo de ~whiptail~ por pantalla (stdout, fd 1) + - la caja de diálogo de ~whiptail~ aparecerá en la pantalla cada vez que se ejecute el ~Makefile~, aunque no instanciemos el target ~install~.. + + el PROBLEMA ocurre porque el comando ~whiptail~ + - escribe en el *stdout (file descriptor 1)* una interfaz gráfica, + - escribe en el *stderr (file descriptor 2)* el resultado de la opción elegida en la interfáz gráfica + - en nuestro ~ifeq~ de GNU Make "creemos" que devuelve (escribe por stdout) un valor booleano ~true~ ó ~false~ + #+END_QUOTE +*** Corregir el problema + #+BEGIN_QUOTE + Si queremos seguir utilizando el comando ~whiptail~, entonces necesitamos + - utilizar la variable ~$?~ que tiene el *Estado de Salida* (exit status) del último comando ejecutado en la Shell + - escapar el símbolo ~$~ de ~$?~ para que *GNU Make* no lo considere como una macro, si no como un caracter común + - verificar el valor de ~$?~ con el comando ~test~ (en reemplazo de ~ifeq~) de la forma ~test $$? -eq 0~ + - si ~$?~ devuelve ~0~ (cero), entonces el comando tuvo éxito (eligieron la opción YES) + - si ~$?~ devuelve distinto de ~0~ (cero), entonces el comando NO tuvo éxito (eligieron la opción NO) + + Otra alternativa a ~whiptail~, sería utilizar el comando ~read~ + #+END_QUOTE +** Solución fallida (2) +*** Problema de la solución + #+BEGIN_QUOTE + - Mismo problema que la *solución fallida (1)* + #+END_QUOTE +*** Código de la Solución fallida + #+BEGIN_SRC makefile + EXIT_STATUS_SUCCESS=0 + CONFIRM_INSTALL=whiptail \ + --yesno "¿Desea confirmar acción?" 0 0 \ + --no-button "Cancelar" --yes-button "Confirmar" + + # - éste target está MAL, porque la expresión que comparamos CONFIRM_INSTALL escribe un cuadro de diálogo sobre la pantalla (stdout, fd 1) + # - el comando whiptail no devuelve un valor booleano, devuelve la interfáz de un cuadro de dialogo + install: + ifeq ($(shell $(CONFIRM_INSTALL) 3>&1 1>&2 2>&3 && echo $$?), $(EXIT_STATUS_SUCCESS)) + @echo "instalando..." + else + @echo "no hago nada" + endif + #+END_SRC +** Alternativa de Solución + #+BEGIN_SRC makefile + i install: check-installed install-utils ## Instalar aplicación + $(BOX_CONFIRM_INSTALL) \ + && test $(EXIT_STATUS) -eq $(EXIT_STATUS_SUCCESS) \ + && (echo $(BASH_ALIAS) >> $(BASH_ALIASES_FILE) \ + && chmod u+x $(UTILS_DIRECTORY)/update-bash-aliases \ + && $(UTILS_DIRECTORY)/update-bash-aliases) \ + || true + #+END_SRC +** Referencias +*** Referencias Issues + 1. [[https://unix.stackexchange.com/questions/603997/makefile-file-exists-check-not-consistent][Makefile file exists check not consistent (unix.stackexchange.com)]] + 2. [[https://stackoverflow.com/questions/32177046/ifeq-conditional-syntax-in-makefile][ifeq conditional syntax in makefile (stackoverflow.com)]] +* GNU Make - Macro con comandos de Shell +** Problema + #+BEGIN_QUOTE + 1) Una macro con un comando de Shell (en este caso ~grep~) que verifique si un archivo contiene un patrón + 2) Si el patrón está en el archivo ejecutar un comando ú otro + #+END_QUOTE +** Sugerencias + #+BEGIN_QUOTE + Si una macro contiene una función ~$(shell ..)~ GNU Make lanzará ERROR + - si la usamos en la receta de una regla como un comando común de Shell junto con operadores lógicos ~&&~ y ~||~ + - si la usamos en la receta de una regla y el Makefile no tiene definido un target con el mismo nombre del resultado que devuelva + + Si una macro contiene una función ~$(shell ..)~ podemos usarla + - como una expresión a evaluar dentro de un condicional ~ifeq~ (Ej. ~ifeq ($(EXISTE_ARCHIVO), true) ...~) + - como un parámetro de un comando de Shell como test, awk, tee, .. + 1) Ej. ~ifeq ($(APP_INSTALLED), true) ...~ (suponiendo que ~APP_INSTALLED~ devuelve un valor booleano) + 2) Ej. ~$(LISTA_COMANDOS) | awk /$(COMANDOS_LINUX)/ | ...~ (en éste caso usariamos ~awk~ como un filtro) + 3) Ej. ~comando && test $(OTRO_COMANDO) -eq 0 && accion si tuvo exito || accion si falla ...~ + #+END_QUOTE +** Solución Fallida - Utilizando el Estado de Salida del último comando ejecutado almacenado en ($?) + #+BEGIN_SRC makefile + EXIT_STATUS=$(shell echo $$?) + EXIT_STATUS_SUCCESS=0 + + # - ésta macro debería ser utilizada como una expresión en un ifeq de GNU Make + # - arrojará ERROR, si la utilizamos en una regla de la forma $(APP_INSTALLED) && .. + APP_INSTALLED=$(shell grep -q "^alias ?='make.*APP_AUTHOR=neverkas" ~/.bash_aliases && echo $$?) + + # éste target va a fallar, por lo dicho arriba + check-installed: + $(APP_INSTALED) \ + && test $(EXIT_STATUS) -eq $(EXIT_STATUS_SUCCESS) \ + && echo "ya está instalada" \ + || true + #+END_SRC +** Solución 1 - Utilizando el Estado de Salida del último comando ejecutado almacenado en ($?) + #+BEGIN_SRC makefile + EXIT_STATUS= $?? + + # dejo comentado para que se entienda que NO siempre es necesario + # usar la función $(shell ) e imprimir un valor con el comando `echo` + # + # EXIT_STATUS=$(shell echo $$?) + + EXIT_STATUS_SUCCESS=0 + + # esto va OK, chequeado + APP_INSTALLED=grep -q "^alias ?='make.*APP_AUTHOR=neverkas" ~/.bash_aliases + + check-installed: + $(APP_INSTALLED) \ + && test $(EXIT_STATUS) -eq $(EXIT_STATUS_SUCCESS) \ + && echo "ya está instalada" \ + || true + #+END_SRC +** Solución 2 - Imprimiendo true en vez del Estado de Salida cero + #+BEGIN_SRC makefile + # verificamos si el archivo .bash_aliases contiene el patrón "^alias ?='make.*APP_AUTHOR=neverkas", + # el comando grep devolverá 0 si tiene éxito y distinto de 0 si no tuvo éxito.. + # + # si el comando grep devuelve 0 entonces se ejecuta el echo true + APP_INSTALLED=$(shell grep -q "^alias ?='make.*APP_AUTHOR=neverkas" ~/.bash_aliases && echo true) + + # nota: se podría haber usado el test $? -eq + check-installed: + ifeq ($(APP_INSTALLED), true) + $(error La aplicación ya está instalada) + endif + #+END_SRC +** Referencias +*** Referencias Oficiales + 1. [[https://www.gnu.org/software/make/manual/html_node/Conditional-Functions.html][Conditional Functions (gnu.org)]] +*** Referencias Extraoficiales + 1. [[https://linuxize.com/post/regular-expressions-in-grep/][Regular Expressions in grep (linuxize.com)]] +*** Referencias Issues + 1. [[https://stackoverflow.com/questions/11287861/how-to-check-if-a-file-contains-a-specific-string-using-bash][How to check if a file contains a specific string using bash (stackoverflow.com)]] + 2. [[https://stackoverflow.com/questions/30078281/raise-error-in-a-bash-script][Raise error in a bash script (stackoverflow.com)]] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f4fe802 --- /dev/null +++ b/Makefile @@ -0,0 +1,180 @@ +-include utils/utils.mk +-include utils/unix-utils.mk +-include config.cfg +-include utils/menus.mk + +#SHELL=/bin/bash + +DOC_NOTES_FILES = $(wildcard $(DOC_NOTES_DIRECTORY)/*.$(DOC_NOTES_EXTENSION)) + +DOC_COMANDOS_LINUX = $(wildcard $(DOC_COMMANDS_LINUX_DIRECTORY)/*.$(DOC_COMMANDS_EXTENSION)) +DOC_SHORTCUTS_LINUX = $(wildcard $(DOC_SHORTCUTS_LINUX_DIRECTORY)/*.$(DOC_SHORTCUTS_EXTENSION)) + +DOC_COMANDOS_APPS = $(wildcard $(DOC_COMMANDS_APPS_DIRECTORY)/*.$(DOC_COMMANDS_EXTENSION)) +DOC_SHORTCUTS_APPS = $(wildcard $(DOC_SHORTCUTS_APPS_DIRECTORY)/*.$(DOC_SHORTCUTS_EXTENSION)) + +COMANDOS_LINUX = $(basename $(notdir $(DOC_COMANDOS_LINUX))) +SHORTCUTS_LINUX = $(basename $(notdir $(DOC_SHORTCUTS_LINUX))) + +COMANDOS_APPS = $(basename $(notdir $(DOC_COMANDOS_APPS))) +SHORTCUTS_APPS = $(basename $(notdir $(DOC_SHORTCUTS_APPS))) + +COMANDOS = $(COMANDOS_LINUX) $(COMANDOS_APPS) + +.DEFAULT_GOAL=help + +# TODO: refactor, definir una función de Makefile que reciba por parámetro el nombre de target y las dependencias +$(DOC_LINUX).txt: $(DOC_COMANDOS_LINUX) + @$(TRUNCATE_CLEAR_CONTENT) $@ + @$(foreach comando, $^,\ + cat $(comando) | \ + sed -n '$(CONTENT_NUMBER_LINE_CATEGORY),$(CONTENT_NUMBER_LINE_DESCRIPTION)p' | \ + nawk 'BEGIN{print "$(basename $(notdir $(comando)))|" } {print $$0}' | \ + sed -E 's/^\#\# ($(CONTENT_TAG_CATEGORY))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2\|/g' | \ + sed -E 's/^\#\# ($(CONTENT_TAG_DESCRIPTION))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2;/g' | \ + tr --delete '\n' | tr ';' '\n' \ + >> $@;\ + ) + +# TODO: refactor, definir una función de Makefile que reciba por parámetro el nombre de target y las dependencias +$(DOC_APPS).txt: $(DOC_COMANDOS_APPS) + @$(TRUNCATE_CLEAR_CONTENT) $@ + @$(foreach comando, $^,\ + cat $(comando) | \ + sed -n '$(CONTENT_NUMBER_LINE_CATEGORY),$(CONTENT_NUMBER_LINE_DESCRIPTION)p' | \ + nawk 'BEGIN{print "$(basename $(notdir $(comando)))|" } {print $$0}' | \ + sed -E 's/^\#\# ($(CONTENT_TAG_CATEGORY))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2\|/g' | \ + sed -E 's/^\#\# ($(CONTENT_TAG_DESCRIPTION))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2;/g' | \ + tr --delete '\n' | tr ';' '\n' \ + >> $@;\ + ) + +$(DOC_NOTES).txt: $(DOC_NOTES_FILES) + @$(TRUNCATE_CLEAR_CONTENT) $@ + @$(foreach nota, $^,\ + cat $(nota) | \ + sed -n '$(CONTENT_NUMBER_LINE_CATEGORY),$(CONTENT_NUMBER_LINE_DESCRIPTION)p' | \ + nawk 'BEGIN{print "$(basename $(notdir $(nota)))|" } {print $$0}' | \ + sed -E 's/^\#\+($(CONTENT_TAG_CATEGORY))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2\|/g' | \ + sed -E 's/^\#\+($(CONTENT_TAG_DESCRIPTION))\: (([[:alnum:]]|[[:space:]]|[[:punct:]])+)$$/\2;/g' | \ + tr --delete '\n' | tr ';' '\n' \ + >> $@;\ + ) + +##@ Listar documentación +l linux-commands: $(DOC_LINUX).txt ## Listado Comandos de terminal Linux + @echo 'Lista de Comandos' + @cat $< | $(SORT_BY_COLUMN) 2 | $(NAWK_ORDER_FIELDS) | $(NAWK_HEADERS) + +a applications-commands: $(DOC_APPS).txt ## Listado Comandos de Aplicaciones + @echo 'Lista de Comandos para Aplicaciones' + @cat $< | $(SORT_BY_COLUMN) 2 | $(NAWK_ORDER_FIELDS) | $(NAWK_HEADERS) + +n notes: $(DOC_NOTES).txt ## Notas sugeridas + @$(MENU_SHOW_NOTES) 3>&1 1>&2 2>&3 \ + | xargs -I % $(EDITOR_NOTE) $(DOC_NOTES_DIRECTORY)/%.$(DOC_NOTES_EXTENSION) + +##@ Creación y Edición de documentación + +# Notas: +# 1. La opción elegida en el menú será capturada por xargs +# 2. La opción capturada será el target que pasaremos por parámetro al propio Makefile para ejecutar +# 3. Con $(MAKE) se invoca a si mismo el Makefile +# 4. El motivo del redireccionamiento se explica en el target linux-create-doc +# TODO: refactor, lógica repetida +create-doc: ## Crear documentación de Linux ó de una Aplicación + @$(MENU_CREATE_DOC) 3>&1 1>&2 2>&3 \ + | xargs -I % $(MAKE) --no-print-directory % + +edit-doc: ## Editar documentación de Linux ó de una Aplicación + @$(MENU_EDIT_DOC) 3>&1 1>&2 2>&3 \ + | xargs -I % $(MAKE) --no-print-directory % + +# TODO: refactor, lógica repetida +linux-edit-commands: $(DOC_LINUX).txt + @$(MENU_EDIT_LINUX_COMMANDS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_COMMANDS_LINUX_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION) + +linux-edit-shortcuts: + @$(MENU_EDIT_LINUX_SHORTCUTS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_SHORTCUTS_LINUX_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION) + +app-edit-commands: + @$(MENU_EDIT_APPS_COMMANDS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_COMMANDS_APPS_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION) + +app-edit-shortcuts: + @$(MENU_EDIT_APPS_COMMANDS) 3>&1 1>&2 2>&3 \ + | xargs -I % $(TEXT_EDITOR) $(DOC_SHORTCUTS_APPS_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION) + +# Notas: +# 1. el comando xargs requiere utilizarlo la forma xargs -I % sh -c 'comando1 %; comando2 %; ..' +# para pasar el mismo parámetro % a multiples comandos en la misma shell +# +# 2. el símbolo % que usamos en los nombres de los ficheros, es el parámetro capturado por el comando xargs con la opción -I +# +# 3. el comando whiptail escribe sobre stdout (fd 2) por tanto creamos un nuevo File Descriptor (3), +# que apunta al stdout (fd 1), para luego redireccionar el stdout->stderr, y redireccionar el stderr->nuevo fd 3 (que apunta al stdout) +linux-create-doc: + @whiptail --inputbox "Escriba el nombre del comando" 25 80 --title "Crear Documentación de Linux" 3>&1 1>&2 2>&3 \ + | xargs -I % sh -c \ + "$(COPY_NOT_OVERWRITE) $(DOC_COMMANDS_LINUX_DIRECTORY)/.template $(DOC_COMMANDS_LINUX_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION); \ + $(COPY_NOT_OVERWRITE) $(DOC_SHORTCUTS_LINUX_DIRECTORY)/.template $(DOC_SHORTCUTS_LINUX_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION); \ + echo 'Se creó el archivo $(DOC_COMMANDS_LINUX_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION);' \ + echo 'Se creó el archivo $(DOC_SHORTCUTS_LINUX_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION);'" + +# TODO: lógica repetida con linux-create-doc +app-create-doc: + @whiptail --inputbox "Escriba el nombre del comando" 25 80 --title "Crear Documentación de Linux" 3>&1 1>&2 2>&3 \ + | xargs -I % sh -c \ + "$(COPY_NOT_OVERWRITE) $(DOC_COMMANDS_APPS_DIRECTORY)/.template $(DOC_COMMANDS_APPS_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION); \ + $(COPY_NOT_OVERWRITE) $(DOC_SHORTCUTS_APPS_DIRECTORY)/.template $(DOC_SHORTCUTS_APPS_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION); \ + echo 'Se creó el archivo $(DOC_COMMANDS_APPS_DIRECTORY)/%.$(DOC_COMMANDS_EXTENSION);' \ + echo 'Se creó el archivo$(DOC_SHORTCUTS_APPS_DIRECTORY)/%.$(DOC_SHORTCUTS_EXTENSION);'" + +# TODO: lógica repetida con COMANDOS_APPS +$(COMANDOS_LINUX): + @test -f $(DOC_SHORTCUTS_LINUX_DIRECTORY)/$@.$(DOC_SHORTCUTS_EXTENSION) \ + && $(BAT) $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.$(DOC_COMMANDS_EXTENSION) $(DOC_SHORTCUTS_LINUX_DIRECTORY)/$@.$(DOC_SHORTCUTS_EXTENSION) \ + || $(BAT) $(DOC_COMMANDS_LINUX_DIRECTORY)/$@.$(DOC_COMMANDS_EXTENSION) + +$(COMANDOS_APPS): + @test -f $(DOC_SHORTCUTS_APPS_DIRECTORY)/$@.$(DOC_SHORTCUTS_EXTENSION) \ + && $(BAT) $(DOC_COMMANDS_APPS_DIRECTORY)/$@.$(DOC_COMMANDS_EXTENSION) $(DOC_SHORTCUTS_APPS_DIRECTORY)/$@.$(DOC_SHORTCUTS_EXTENSION) \ + || $(BAT) $(DOC_COMMANDS_APPS_DIRECTORY)/$@.$(DOC_COMMANDS_EXTENSION) + +##@ Utilidades +h help: ## Mostrar menú de ayuda + @awk 'BEGIN {FS = ":.*##"; printf "\nOpciones para usar:\n make \033[36m\033[0m\n"} /^[$$()% 0-9a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +install-utils: +ifeq ("$(shell which bat)","") + @sudo aptitude install -y bat +endif + +ri re-install: remove install + +check-installed: +ifeq ($(APP_INSTALLED), true) + $(error La aplicación ya está instalada) +endif + +i install: check-installed install-utils ## Instalar aplicación + @$(BOX_CONFIRM_INSTALL) \ + && test $(EXIT_STATUS) -eq $(EXIT_STATUS_SUCCESS) \ + && (echo $(BASH_ALIAS) >> $(BASH_ALIASES_FILE) \ + && chmod u+x $(UTILS_DIRECTORY)/update-bash-aliases \ + && $(UTILS_DIRECTORY)/update-bash-aliases) \ + || true + +r remove: ## Desinstalar aplicación + @$(BOX_CONFIRM_UNINSTALL) \ + && test $(EXIT_STATUS) -eq $(EXIT_STATUS_SUCCESS) \ + && sed -i "/^alias $(BASH_ALIAS_SYMBOL)='make.*APP_AUTHOR=$(APP_AUTHOR)/d" $(BASH_ALIASES_FILE) \ + && $(UTILS_DIRECTORY)/update-bash-aliases \ + || true + +# %: +# $(error NO existe el comando) + +.PHONY: i install ri re-install install-utils r remove h help l linux-commands a applications-commands n notes diff --git a/README.org b/README.org new file mode 100644 index 0000000..d37b52d --- /dev/null +++ b/README.org @@ -0,0 +1,71 @@ +#+TITLE: Command Helper +* Intro +** ¿Qué es? + - programa sencillo sin tantas dependencias, similar al comando ~man~ para documentar comandos + - describe los comandos más utiles en un archivo ~.sh~ + - describe los atajos más comunes en un archivo ~.org~ + - accede desde una terminal de forma global con el símbolo ~?~ +** ¿Por qué lo utilizo? + - no utilizar ciertos comandos por un tiempo, implíca olvidarse de como usarlos y sus parámetros + - evitar perder tiempo leyendo ~man comando~ que tiene tantas opciones avanzadas en vez una explicación simple +* Ejemplo + #+BEGIN_SRC shell + # imprimirá un menú de ayuda, opciones de instalación, etc.. + ? help + + # leerá las entradas documentadas del comando ls + # con los usos más comunes que hayas escrito + ? ls + + # leerá las entradas del archivo doc/linux-shell/commands/screen.sh y también doc/linux-shell/shortcuts/screen.org (si los tuviera) + ? screen + #+END_SRC +* Instalación y Desinstalación + #+BEGIN_SRC shell + # se agregará un alias de bash del directorio actual en ~/.bash_aliases + # que te permitirá ejecutar el programa en la terminal usando sólo el símbolo de interrogación + make install + + # para desinstalar + # eliminará el código de ~/.bash_aliases y también el alias vinculada a la shell + make remove + #+END_SRC +* Configuración +** Documentando comandos y shortcuts + #+BEGIN_QUOTE + La configuración para documentar un nuevo comando de la terminal de linux es mínima + 1. Creamos el archivo con el nombre del comando a documentar en el directorio ~doc/linux-shell/commands/~ con la extensión ~.sh~ + 2. También podemos crear una tabla de los shortcuts del comando en ~doc/linux-shell/shortcuts/~ con la extensión ~.org~ + 3. Listo! podemos reutilizar los archivos creados como template + + Documentar comandos de aplicaciones es lo mismo, pero usamos el directorio ~doc/applications/commands~ y ~doc/applications/shortcuts/~ + #+END_QUOTE +** Metadata al documentar + Al comienzo de cada archivo ~.sh~ debe tener las siguientes dos lineas (es importante respetar el formato) + - ~## CATEGORIA: texto~ clasifica el comando en un grupo particular + - ~## DESCRIPCION: texto~ describe el comando en si, que es lo que hace + + #+BEGIN_QUOTE + El siguiente sería un ejemplo del archivo ~doc/commands/ls.sh~ para entender la metadata + #+END_QUOTE + + #+BEGIN_SRC shell + ## CATEGORIA: operaciones con archivo + ## DESCRIPCION: listar archivos y directorios + + # listar archivos ocultos + ls -la + + # listar archivos ordenados por tamaño del archivo + ls -ls + #+END_SRC +* Referencias +** Referencias Extraoficiales + #+BEGIN_COMMENT + pendiente validar + 1) https://www.fpgenred.es/GNU-Linux/ + 2) https://www.tecmint.com/category/linux-commands/ + 3) https://linuxopsys.com/ + 4) https://geekland.eu/category/linux-2/ + 5) https://phoenixnap.com/kb/tag/linux + #+END_COMMENT diff --git a/config.cfg b/config.cfg new file mode 100644 index 0000000..052e999 --- /dev/null +++ b/config.cfg @@ -0,0 +1,41 @@ +# utilizado en los popup_edit +TEXT_EDITOR=nvim + +# utilizado en un cat archivo | sed -n '1p' +# (sólo imprimirá ese número de linea) +CONTENT_NUMBER_LINE_CATEGORY=1 +CONTENT_NUMBER_LINE_DESCRIPTION=2 + +# utilizados en un cat archivo | sed -E 's/^(content_tag_here): (.*)$/ \2/g' +# (obtener el texto de las lineas que contengan esos tags al principio) +CONTENT_TAG_CATEGORY=CATEGORIA +CONTENT_TAG_DESCRIPTION=DESCRIPCION + +# utilizado en un bat --line-range 4: archivo +# (imprimirá a partir de ese numero de linea hasta el final del archivo) +NUMBER_LINE_BEGIN_DOCUMENTATION=4 +NUMBER_LINE_BEGIN_DOC_NOTES=3 + +UTILS_DIRECTORY=utils + +DOC_DIRECTORY=doc + +DOC_COMMANDS_DIRECTORY=commands +DOC_COMMANDS_EXTENSION=sh + +DOC_SHORTCUTS_DIRECTORY=shortcuts +DOC_SHORTCUTS_EXTENSION=org + +DOC_NOTES_EXTENSION=org + +DOC_APPS=applications +DOC_LINUX=linux-shell +DOC_NOTES=notes + +DOC_COMMANDS_LINUX_DIRECTORY=$(DOC_DIRECTORY)/$(DOC_LINUX)/$(DOC_COMMANDS_DIRECTORY) +DOC_SHORTCUTS_LINUX_DIRECTORY=$(DOC_DIRECTORY)/$(DOC_LINUX)/$(DOC_SHORTCUTS_DIRECTORY) + +DOC_COMMANDS_APPS_DIRECTORY=$(DOC_DIRECTORY)/$(DOC_APPS)/$(DOC_COMMANDS_DIRECTORY) +DOC_SHORTCUTS_APPS_DIRECTORY=$(DOC_DIRECTORY)/$(DOC_APPS)/$(DOC_SHORTCUTS_DIRECTORY) + +DOC_NOTES_DIRECTORY=$(DOC_DIRECTORY)/notes \ No newline at end of file diff --git a/doc/applications/commands/.template b/doc/applications/commands/.template new file mode 100644 index 0000000..5dc5909 --- /dev/null +++ b/doc/applications/commands/.template @@ -0,0 +1,8 @@ +## CATEGORIA: clasificar aplicación +## DESCRIPCION: describir aplicación + +# un comentario, imprimimos un hola +echo "hola" + +# otro comentario, imprimimos un chau +echo "chau" \ No newline at end of file diff --git a/doc/applications/commands/docker.sh b/doc/applications/commands/docker.sh new file mode 100644 index 0000000..102c471 --- /dev/null +++ b/doc/applications/commands/docker.sh @@ -0,0 +1,6 @@ +## CATEGORIA: contenedores y maquinas virtuales +## DESCRIPCION: empaqueta aplicaciones en contenedores similares a maquinas virtuales + +# eliminar todas las imagenes en desuso que son más antiguas a un número de horas +# (https://docs.docker.com/engine/reference/commandline/image_prune/) +docker image prune -a --force --filter "until=1h" diff --git a/doc/applications/commands/logseq.sh b/doc/applications/commands/logseq.sh new file mode 100644 index 0000000..71d5fb5 --- /dev/null +++ b/doc/applications/commands/logseq.sh @@ -0,0 +1,2 @@ +## CATEGORIA: gestión de notas y tareas +## DESCRIPCION: gestor de conocimiento personal, grafos de conocimientos (vincula ideas) diff --git a/doc/applications/commands/neovim.sh b/doc/applications/commands/neovim.sh new file mode 100644 index 0000000..48b16bc --- /dev/null +++ b/doc/applications/commands/neovim.sh @@ -0,0 +1,14 @@ +## CATEGORIA: editor de texto +## DESCRIPCION: editor de texto basado en Vim + +# Desactivar las palabras resaltadas hasta la próxima búsqueda +:noh + +# Mostrar número de linea +:setnumber + +# Buscar/Reemplazar en la misma linea que el cursor +.s/cadena/nueva/g + +# Buscar/Reemplazar globalmente pero pide confirmación al reemplazar +s/cadena/nueva/gc diff --git a/doc/applications/commands/qutebrowser.sh b/doc/applications/commands/qutebrowser.sh new file mode 100644 index 0000000..e5af027 --- /dev/null +++ b/doc/applications/commands/qutebrowser.sh @@ -0,0 +1,8 @@ +## CATEGORIA: navegador web +## DESCRIPCION: navegador web minimalista basado en Vim + +# Cerrar navegador +:q + +# Guardar las pestañas y cerrar Navegador +:wq diff --git a/doc/applications/shortcuts/.template b/doc/applications/shortcuts/.template new file mode 100644 index 0000000..d53bca2 --- /dev/null +++ b/doc/applications/shortcuts/.template @@ -0,0 +1,11 @@ +#+NAME: atajos +| Atajo | Descripción | +|------------+-----------------| +| Alt + F4 | Cerrar programa | +| Ctrl Alt F | Abrir terminal | + +#+NAME: otros-atajos +| Atajo | Descripción | +|------------+-----------------| +| Alt + F4 | Cerrar programa | +| Ctrl Alt F | Abrir terminal | \ No newline at end of file diff --git a/doc/applications/shortcuts/logseq.org b/doc/applications/shortcuts/logseq.org new file mode 100644 index 0000000..6ac8899 --- /dev/null +++ b/doc/applications/shortcuts/logseq.org @@ -0,0 +1,8 @@ +| Atajo | Descripción | +|-----------------------------+----------------------------------------------------| +| t r | Toggle right sidebar | +| t l | Toggle left sidebar | +| t o | Toggle open blocks (collapse or expand all blocks) | +| Ctrl w | close logseq | +| Shift Alt UpArrow/DownArrow | Deslizar tareas | +| Ctrl K | Search or Create a Page | diff --git a/doc/applications/shortcuts/neovim.org b/doc/applications/shortcuts/neovim.org new file mode 100644 index 0000000..6d8dc24 --- /dev/null +++ b/doc/applications/shortcuts/neovim.org @@ -0,0 +1,26 @@ +| Atajo | Descripción | +|-------------------+-------------------------------------------------------| +| k,j,h,l | Mover cursor up, down, left, right | +| r+nuevoCaracter | Sustituir el caracter donde esté el cursor | +| f+caracterABuscar | Buscar caracter desde el cursor hasta fin de linea | +| F+caracterABuscar | Buscar caracter desde el cursor al principio de linea | + +| Atajo | Descripción | +|-------+------------------------------------------| +| gg | Cursor al principio del archivo | +| G | Cursor al fin del archivo | +| w | Avanzar a la siguiente palabra | +| b | Retroceder a la anterior palabra | +| 0 | Cursor al principio de linea | +| $ | Cursor al fin de linea | +| i | Editar en donde esté el cursor | +| a | Editar un caracter adelante al cursor | +| I | Editar en el primer caracter de la linea | +| A | Editar al fin de linea | + +| Atajo | Descripción | +|-------+-----------------------------------------------------------------------------| +| v+$ | Seleccionar texto hasta fin de linea | +| v+^ | Seleccionar texto hasta el principio de linea | +| v+% | Seleccionar texto hasta donde balancee alguno de los operadores (,{, [ | +| 5i* | Repetir 5 veces el escribir el símbolo asterisco (util para separar textos) | diff --git a/doc/applications/shortcuts/qutebrowser.org b/doc/applications/shortcuts/qutebrowser.org new file mode 100644 index 0000000..da96602 --- /dev/null +++ b/doc/applications/shortcuts/qutebrowser.org @@ -0,0 +1,44 @@ +#+NAME: similares-a-vim +| Atajo | Descripción | +|---------+-------------------------------------------| +| k,j,h,l | Scrollea hacia (k)arriba y (j)abajo | +| h,l | Scrollea hacia (h)izquierda y (l)derecha | +| gg | Scrollea al principio del de la página | +| G | Scrollea al final del de la página | +|---------+-------------------------------------------| +| yy | copiar url | +| yt | copiar título al portapapeles (clipboard) | +| pp | abrir url del portapapeles (clipboard) | +| Pp | igual que pp, pero en una nueva pestaña | +|---------+-------------------------------------------| +| / | Buscar texto en la pestaña actual | +| n | Mover búsqueda hacia delante | +| N | Mover búsqueda hacia atrás | +|---------+-------------------------------------------| + +#+NAME: gestionar-tabs +| Atajo | Descripción | +|--------------+-------------------------------------------| +| gt | Elegir una pestaña con un buscador | +| gl | Mover pestaña (tab) a la izquierda (left) | +| gr | Mover pestaña (tab) a la derecha (right) | +| d | Cerrar pestaña actual | +| Alt + numero | Moverse a una pestaña por su posición | +|--------------+-------------------------------------------| + +#+NAME: historial +| Atajo | Descripción | +|-------+------------------------------------------------------| +| o | Abrir una página a partir de una lista del historial | +| O | Igual que o, pero en una nueva pestaña | +|-------+------------------------------------------------------| +| H | Se mueve hacia atrás en el historial | +| L | Se mueve hacia delante en el historial | +|-------+------------------------------------------------------| + +#+NAME: Otros +| Atajo | Descripción | +|---------+-------------------------------------------| +| + | Aumentar tamaño de la página (zoom-in) | +| - | Disminuir tamaño de la página (zoom-out) | +|---------+-------------------------------------------| diff --git a/doc/linux-shell/commands/.template b/doc/linux-shell/commands/.template new file mode 100644 index 0000000..f793122 --- /dev/null +++ b/doc/linux-shell/commands/.template @@ -0,0 +1,8 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# un comentario, imprimimos un hola +echo "hola" + +# otro comentario, imprimimos un chau +echo "chau" \ No newline at end of file diff --git a/doc/linux-shell/commands/amixer.sh b/doc/linux-shell/commands/amixer.sh new file mode 100644 index 0000000..5605c82 --- /dev/null +++ b/doc/linux-shell/commands/amixer.sh @@ -0,0 +1,19 @@ +## CATEGORIA: audio +## DESCRIPCION: controla el volumen del sistema + +# modificar el volumen principal al 50% +# (usar %+ y %- para incrementar y decrementar el valor actual) +amixer set Master 50% + +# sube el volumen principal en un 50% +amixer set Master 50%+ + +# baja el volumen principal en un 50% +amixer set Master 50%- + +# silencia el volumen principal +amixer set Master mute + +# saca el silencio del volumen principal +amixer set Master unmute + diff --git a/doc/linux-shell/commands/cal.sh b/doc/linux-shell/commands/cal.sh new file mode 100644 index 0000000..8352931 --- /dev/null +++ b/doc/linux-shell/commands/cal.sh @@ -0,0 +1,21 @@ +## CATEGORIA: otros +## DESCRIPCION: calendario + +# mostrar el mes actual del calendario (mes actual, año actual) +cal + +# mostrar un mes del calendario (mes=1, año=2023) +cal 1 2023 + +# mostrar del año actual.. el mes de Junio +cal -m June + +# mostrar del año actual.. el mes anterior, el actual y el siguiente +cal -3 + +# mostrar calendario completo del año actual +cal -y + +# mostrar calendario completo (año=2050) +cal 2050 + diff --git a/doc/linux-shell/commands/column.sh b/doc/linux-shell/commands/column.sh new file mode 100644 index 0000000..ede1dac --- /dev/null +++ b/doc/linux-shell/commands/column.sh @@ -0,0 +1,19 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# listar las cuentas de usuario del sistema en un formato más entendible +# - la opción -t (table) refiere a visualizar los datos en un formato de tabla) +# - la opción -s (separator) solicita el caracter que actúa como Separador de columnas (Ej. en .csv es la coma) +column -t -s ":" /etc/passwd + +# listar todos los archivos y directorios en un 5 columnas +# (podemos omitir la opción -t ó --verbose, son sólo para entender que ocurre) +ls -a /home/jelou/Descargas | xargs --verbose --max-args=5 | column -t -s " " +ls -a /home/jelou/Descargas | xargs -t -n 5 | column -t -s " " + +# Comando para completar un archivo como dataset para utilizar el comando column +# echo "numero_legajo,nombre,fecha_nacimiento" >> alumnos.csv && (seq 9 | xargs -I % echo "00%,desconocido,199%" >> alumnos.csv +# +# listar contenido de un archivo CSV en columnas +# (el formato .csv usa el caracter de la coma "," como delimitador para separar las columnas) +column -t -s "," alumnos.csv diff --git a/doc/linux-shell/commands/curl.sh b/doc/linux-shell/commands/curl.sh new file mode 100644 index 0000000..3a92109 --- /dev/null +++ b/doc/linux-shell/commands/curl.sh @@ -0,0 +1,8 @@ +## CATEGORIA: transferencia de datos +## DESCRIPCION: operaciones de transferencia de datos (get, post, put, delete) + +# descargar un archivo a la ruta actual (la opción -O es de output) +curl -O https://www.gnu.org/licenses/gpl-3.0.txt + +# visualizar un archivo (la opción -s es de silent, oculta barra de progreso y los errores) +curl -s https://www.gnu.org/licenses/gpl-3.0.txt diff --git a/doc/linux-shell/commands/cut.sh b/doc/linux-shell/commands/cut.sh new file mode 100644 index 0000000..2d1f5a5 --- /dev/null +++ b/doc/linux-shell/commands/cut.sh @@ -0,0 +1,34 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# Listar el nombre de usuario de las cuentas del sistema que tengan la Shell Bash por default +# +# - la opción --fields de cut, indicamos que columnas queremos imprimir separadas por comas (en este ej. sólo la primera) +# - la opción --delimiter, indicamos el símbolo que delimita las columnas del archivo a mostrar (en este caso los :) +# - comando grep, filtramos las lineas del archivo que incluya ese string +grep "/bin/bash" /etc/passwd | cut --delimiter=':' --fields=1 +grep "/bin/bash" /etc/passwd | cut -d ':' -f 1 + +# lo mismo que antes, pero.. si queremos mostrar columnas específicas +grep "/bin/bash" /etc/passwd | cut --delimiter=':' --fields=1,2,5,6 + +# Listar las cuentas del sistema que tengan la Shell Bash por default +# +# - la opcion --fields de cut, permite un rango de columnas (en este ejemplo desde la columna 1 hasta la 6) +grep "/bin/bash" /etc/passwd | cut --delimiter=':' --fields=1-6 +grep "/bin/bash" /etc/passwd | cut -d ':' -f 1-6 + +# Reemplazar el delimitador de columna +grep "/bin/bash" /etc/passwd | cut --delimiter=':' --fields=1-6 --output-delimiter=',' + +# Mostrar los 10 comandos más utilizados (en la sesión de la terminal activa) +# +# - la opción --characters=8, selecciona el caracter en la posición 8 +# - la opción --characters=1,2,3,4, selecciona el caracter de las posiciones 1,2,3,4 +# - la opción --characters=1-8, selecciona el caracter desde la posición 1 hasta la posición 8 +# - la opción (elegida) --characters=8-, selecciona el caracter desde la posición 8 en adelante (no necesitamos indicar la posición del último char) +# +# - uniq reporta lineas repetidas de un archivo, mostrándolas sólo una vez (suponiendo que están ordenadas Ej. con el comando sort) +# - la opción --count de uniq, agrega el número de veces que se repite cada linea +history | cut --characters=8- | sort | uniq --count | sort --numeric-sort --reverse | head --lines=10 +history | cut -c 8- | sort | uniq -c | sort -rn | head diff --git a/doc/linux-shell/commands/fish.sh b/doc/linux-shell/commands/fish.sh new file mode 100644 index 0000000..8065ca7 --- /dev/null +++ b/doc/linux-shell/commands/fish.sh @@ -0,0 +1,2 @@ +## CATEGORIA: shell +## DESCRIPCION: shell interactiva diff --git a/doc/linux-shell/commands/ls.sh b/doc/linux-shell/commands/ls.sh new file mode 100644 index 0000000..03af3cb --- /dev/null +++ b/doc/linux-shell/commands/ls.sh @@ -0,0 +1,26 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: listar directorios y archivos + +# contar cantidad de archivos/directorios +ls | wc -c + +# filtrar las entradas del directorio sin usar `grep` +ls *pdf + +# listar archivos ocultos +ls -la + +# listar archivos ordenados por fecha de creación/actualización +ls -lt + +# listar archivos ordenados por tamaño del archivo +ls -ls + +# listar archivos ordenados por tamaño del archivo (en un formato más entendible) +ls -lsh + +# listar los 4 archivos más recientes +ls -lth | head -n4 + +# listar los 2 archivos más antiguos +ls -lth | tail -n2 diff --git a/doc/linux-shell/commands/mv.sh b/doc/linux-shell/commands/mv.sh new file mode 100644 index 0000000..9efceb3 --- /dev/null +++ b/doc/linux-shell/commands/mv.sh @@ -0,0 +1,8 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: listar directorios y archivos + +# mover todos los archivos y directorios a un directorio, excluyendo el directorio destino +mv $(ls --ignore=apps/) apps/ + +# mover todos los archivos a una ruta excluyendo algunos directorios y archivos +mv $(ls --ignore=.git/ --ignore=.gitignore) nuevo-path/app diff --git a/doc/linux-shell/commands/pgrep.sh b/doc/linux-shell/commands/pgrep.sh new file mode 100644 index 0000000..59e5855 --- /dev/null +++ b/doc/linux-shell/commands/pgrep.sh @@ -0,0 +1,37 @@ +## CATEGORIA: información sobre los Procesos +## DESCRIPCION: describir comando +## NOTAS SUGERIDAS: tty-pts + +# Obtener pid de un proceso (de cualquier usuario logeado) +pgrep firefox + +# Listar todos los procesos de la forma (pid, nombre) asociados a una Terminal (llamadas TTY ó Consola Virtual) +# +# - útil cuando uno usuario ó diferentes usuarios se conectan al mismo Sistema a través de diferentes terminales (tty1, tty2, ...) +# +pgrep --terminal tty2 --list-name +pgrep -t tty2 -l + +# Obtener de un usuario logeado, el pid de un proceso específico +pgrep --euid jelou firefox +pgrep -u jelou firefox + +# Contar la cantidad de procesos de un usuario +pgrep --count --euid jelou +pgrep -c -u jelou + +# Listar todos los procesos (pid, nombre) asociados a un usuario +pgrep --euid jelou --list-name +pgrep -u jelou -l + +# Listar todos los procesos (pid, comando) asociados a un usuario +pgrep --euid jelou --list-full +pgrep -u jelou -a + +# Listar el proceso más reciente (pid, nombre) asociado a un usuario +pgrep --euid jelou --newest --list-name +pgrep -u jelou -n -l + +# Listar el proceso más antiguo (pid, nombre) asociado a un usuario +pgrep --euid jelou --oldest --list-name +pgrep -u jelou -o -l diff --git a/doc/linux-shell/commands/screen.sh b/doc/linux-shell/commands/screen.sh new file mode 100644 index 0000000..89294b8 --- /dev/null +++ b/doc/linux-shell/commands/screen.sh @@ -0,0 +1,14 @@ +## CATEGORIA: terminales +## DESCRIPCION: multiplexor de terminales (crear multiples instancias de terminal en una sesión) + +# crear una sesión con nombre +screen -S nombre + +# listar sesiones +screen -ls + +# vincular una sesión (por nombre ó id) a la terminal actual +screen -r nombre + +# cerrar una sesión +screen -X -S nombre quit diff --git a/doc/linux-shell/commands/sort.sh b/doc/linux-shell/commands/sort.sh new file mode 100644 index 0000000..157b4e7 --- /dev/null +++ b/doc/linux-shell/commands/sort.sh @@ -0,0 +1,27 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: ordenar archivos de texto (útil si tienen un formato csv ó similar) + +# Ejemplos para rellenar un archivo con datos y probar el siguiente comando sort +# truncate --size=0 alumnos.txt && seq 10 | xargs -I{} echo "alumno {}" >> alumnos.txt +# cat /dev/null > alumnos.txt && i=1; while [[ $i -le 10 ]]; do echo "alumno $i" >> alumnos.txt; let i++; done +# echo -n "" > alumnos.txt && i=1; while (( $i < 10+1 )); do echo "alumno $i" >> alumnos.txt; ((i++)); done +# +# ordenar un archivo por la segunda columna (numérica) de forma descendente +sort alumnos.txt --key=2 --numeric-sort +sort alumnos.txt -k 2 -n +sort alumnos.txt -nk 2 + +# Ejemplos para rellenar un archivo con datos y probar el siguiente comando sort +# truncate --size=0 alumnos.txt && seq 10 | xargs -I{} echo "pepe | argentino | {}" >> alumnos.txt && sed -i '1,2 s/a/c/; 3,5 s/a/z/; 6,8 s/a/c/' alumnos.txt +# +# ordenar un archivo por la segunda columna y que tiene el símbolo | pipe como delimitador (separador de campos) +sort alumnos.txt --field-separator "|" --key=2 +sort alumnos.txt -t "|" -k 2 +sort alumnos.txt -k 2 + +# Ejemplo para rellenar el archivo con datos y probar el siguiente comando sort +# echo -n "" > nombres-duplicados.txt && timeout 5 bash -c 'while true; do echo "escribiendo.."; echo "carlos" >> nombres-duplicados.txt ; sleep 1; done;' +# +# remover las lineas repetidas +sort --unique nombres-duplicados.txt > nombres-sin-repetir.txt +sort -u nombres-duplicados.txt > nombres-sin-repetir.txt diff --git a/doc/linux-shell/commands/tar.sh b/doc/linux-shell/commands/tar.sh new file mode 100644 index 0000000..4d03afc --- /dev/null +++ b/doc/linux-shell/commands/tar.sh @@ -0,0 +1,29 @@ +## CATEGORIA: archivador +## DESCRIPCION: comprimir/descomprimir archivos y directorios + +# extraer archivos en la ruta actual +# - (x) extract : extraer +# - (v) verbose: describe los pasos de forma verbosa +# - (f) file: especificar el archivo +tar -xvf videos-humor.tar +tar -xvf videos-humor.tar.gz + +# extraer archivos en una ruta específica +tar -xvf videos-humor.tar.gz -C ~/Videos/ + +# comprimir archivo +# - (c): create: crear archivo +tar -cvf videos-humor.tar ~/Videos/humor + +# comprimir archivo con formato gzip +# (z): gzip: comprimir con gzip +tar -cvzf videos-humor.tar.gz ~/Videos/humor + +# filtrar archivos y no incluir los archivos con extensión .mp3 +tar -cvzf videos-humor.tar.gz ~/Videos/humor --exclude=*.mp3 + +# listar archivos +tar -tf videos-humor.tar + +# listar archivos con detalles +tar -tvf videos-humor.tar diff --git a/doc/linux-shell/commands/tee.sh b/doc/linux-shell/commands/tee.sh new file mode 100644 index 0000000..732cee7 --- /dev/null +++ b/doc/linux-shell/commands/tee.sh @@ -0,0 +1,36 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: leer de la (stdin) e imprimir en la (stdout) lo que escribe en archivos + +# 1. Escribir en un archivo e imprimir en pantalla (escribir en STDOUT, file descriptor 1), el resultado de un comando que imprime en pantalla (STDOUT) +# +# - imprimir en pantalla es lo mismo que escribir en (STDOUT, file descriptor 1) +# - la opción --append de tee, agrega el contenido al archivo sin borrar el contenido que tuviese +ping google.com \ + | tee --append ping.txt + +ping google.com \ + | tee -a ping.txt + +# 2. Escribir en un archivo lo que se escribe en pantalla (STDOUT, file descriptor 1) +# +# - estamos utilizando el operador de redirección >> de la forma 1>>archivo (por default utiliza el fd 1) +# - el operador de redirección >> no imprimir por pantalla (STDOUT) lo que escribe en el archivo, pero lo hace el comando tee +ping google.com \ + >> ping.txt + +ping google.com \ + 1>> ping.txt + +# 3. Redireccionar el resultado de un comando a un archivo y a la pantalla (STDOUT), +# y finalizar su ejecución pasado un tiempo limite +# +# - el comando timeout, envía una señal de interrupción SIGTERM para finalizar la ejecución de los comandos (ping y tee) +timeout 5s ping google.com \ + | tee -a ping.txt + +# 4. Redireccionar un resultado a múltiples archivos +echo "TODO: personajes en 3d" \ + | tee --append TODO.md CHANGELOG.md + +echo "TODO: sprites livianos" \ + | tee -a TODO.md CHANGELOG.md diff --git a/doc/linux-shell/commands/timeout.sh b/doc/linux-shell/commands/timeout.sh new file mode 100644 index 0000000..b5f64ef --- /dev/null +++ b/doc/linux-shell/commands/timeout.sh @@ -0,0 +1,29 @@ +## CATEGORIA: - +## DESCRIPCION: Ejecuta un comando por un tiempo límite + +# ejecutar por 5 segundos, un loop infinito que hace operaciones de escritura +echo -n "" > duplicados.txt && timeout 5 bash -c 'while true; do echo "escribiendo.."; echo "carlos" >> duplicados.txt ; sleep 1; done;' + +# ejecutar por 10 segundos el comando ping (verifica el estado de un servidor haciendo ping) +timeout 10s ping localhost + +# ejecutar por 1 minuto, el comando top (lista el estado de los procesos del sistema operativo) +timeout 1m top + +# ejecutar por 1 hora, el comando tail -f para observar un log +timeout 1h tail -f /var/log/syslog + +# por defecto utiliza la unidad de tiempo en segundos +timeout 10 ping localhost + +# indicar el nombre de la señal para detener el proceso (por defecto es SIGTERM) +timeout -s SIGKILL 10 ping localhost + +# indicar el número de la señal para detener el proceso +# (para conocer el número ejecutar kill -l) +timeout -s 9 10 ping localhost + +# manera más sencilla de mandar la señal SIGKILL +timeout --kill-after=10 ping localhost +timeout -k 10 ping localhost + diff --git a/doc/linux-shell/commands/tr.sh b/doc/linux-shell/commands/tr.sh new file mode 100644 index 0000000..182d066 --- /dev/null +++ b/doc/linux-shell/commands/tr.sh @@ -0,0 +1,61 @@ +## CATEGORIA: operaciones con la (stdin) y (stdout) +## DESCRIPCION: manipular, modificar ó eliminar texto (similar al comando sed) + +# transformar texto a mayúsculas +echo "clojure for the brave and true.pdf" | tr 'a-z' 'A-Z' # a-z toma un rango de caracteres +echo "clojure for the brave and true.pdf" | tr '[:lower:]' '[:upper:]' # utilizamos Clases de Caracteres +echo "clojure for the brave and true.pdf" | sed -E 's/(.+)/\U\1/' # en una regex compleja haría dificil la lectura + +# transformar texto a minúsculas +echo "CLOJURE for the BRAVE and true.pdf" | tr 'A-Z' 'a-z' +echo "CLOJURE for the BRAVE and true.pdf" | tr '[:upper:]' '[:lower:]' +echo "CLOJURE for the BRAVE and TRUE.pdf" | sed -E 's/(.+)/\L\1/' # en una regex compleja dificultaría la lectura + +# sustituir espacios por guiones (comando tr Vs comando sed) +echo "clojure for the brave and true.pdf" | tr ' ' '-' +echo "clojure for the brave and true.pdf" | sed 's/ /-/g' + +# listar los directorios de la variable de entorno PATH con saltos de linea (comando tr Vs comando sed) +echo ${PATH} | tr ':' '\n' +echo ${PATH} | sed 's/:/\n/g' + +# transformar hipervínculo de markdown a orgmode (comando tr Vs comando sed) +echo "[Guía de ORG Mode](https://orgmode.org/guide)" | tr '()' '[]' | sed -E 's/(.*)/[\1]/' # hará desastres en un archivo markdown +echo "[Guía de ORG Mode](https://orgmode.org/guide)" | sed -E 's/\((.*)\)/[\1]/; s/(.*)/[\1]/' +echo "[Guía de ORG Mode](https://orgmode.org/guide)" | sed -E 's/\[(.*)\]\((.*)\)/[[\1][\2]]/' # menos probable de fallar + +# sustituir distintos caracteres.. (comando tr Vs comando sed) +# (Ej. los espacios por guiones, las mayúsculas por minúsculas) +echo "CLOJURE for the BRAVE and TRUE.pdf" | tr ' [A-Z]' '-[a-z]' # más entendible +echo "CLOJURE for the BRAVE and TRUE.pdf" | sed -E 's/[[:space:]]/\-/g; s/(.+)/\L\1/' + +# sustituir palabras diferentes.. +# Nota: el comando tr opera sobre caracteres no sobre strings, el comando sed sería el más adecuado para esta tarea +echo "clojure for the brave and true.pdf" | sed 's/clojure/javascript/g; s/brave/false/g' + +# eliminar espacios en blanco (comando tr Vs comando sed) +echo "clojure for the brave and true.pdf" | tr --delete ' ' +echo "clojure for the brave and true.pdf" | tr -d ' ' + +echo "clojure for the brave and true.pdf" | sed 's/ //g' +echo "clojure for the brave and true.pdf" | sed 's/[[:space:]]//g' + +# remover todos los caracteres que NO sean legibles +# Nota: el [:print:] del comando sed no es tan eficiente para éste objetivo, NO logra el mismo resultado +head -n1 /dev/urandom | tr --complement --delete '[:print:]\n' +head -n1 /dev/urandom | tr -cd '[:print:]\n' + +# sustituir cualquier caracter que no sea alfanumérico (comando tr Vs comando sed) +# Nota: en una regex ^[EXP] hace de Complemento, buscamos todo lo que no coincida con EXP +echo "clojure for the brave and true.pdf" | tr --complement '[:alnum:]' '-' +echo "clojure for the brave and true.pdf" | tr -c '[:alnum:]' '-' + +echo "clojure for the brave and true.pdf" | sed 's/[^[:alnum:]]/-/g' + +# remover caracteres repetidos +# (Ej. nombre de archivos con exceso de guiones o espaciado) +echo "clojure--for---the-brave-and-----true.pdf" | tr --squeeze-repeats '-' +echo "clojure--for---the-brave-and-----true.pdf" | tr -s '-' + +echo "clojure for the brave and true.pdf" | tr --squeze-repeats '[:space:]' +echo "clojure for the brave and true.pdf" | tr -s '[:space:]' diff --git a/doc/linux-shell/commands/truncate.sh b/doc/linux-shell/commands/truncate.sh new file mode 100644 index 0000000..23c72a4 --- /dev/null +++ b/doc/linux-shell/commands/truncate.sh @@ -0,0 +1,15 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: recorta el tamaño de un archivo (ó bien se dice truncar un archivo) + +# Limpiar el contenido del archivo, lo deja con 0 Bytes +truncate -s 0 archivo.txt + +# Trunca el archivo a 100 Bytes (si era de 10Mb, entonces se perderán datos) +truncate -s 100 archivo.txt + +# Aumenta el tamaño del archivo en +100k (es decir 100*1024 Bytes) +# Nota: las unidades son K,M,G,T,P y son potencias de 1024 Bytes +truncate -s +100k archivo.txt + +# Reduce el tamaño del archivo en -100k +truncate -s -100k archivo.txt diff --git a/doc/linux-shell/commands/uniq.sh b/doc/linux-shell/commands/uniq.sh new file mode 100644 index 0000000..d045e42 --- /dev/null +++ b/doc/linux-shell/commands/uniq.sh @@ -0,0 +1,45 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# Mostrar los 5 mensajes del syslog que más se repitan, y la cantidad de veces que se repiten +cut --characters=17- /var/log/syslog | sort | uniq --count | sort --numeric-sort --reverse | head --lines=5 + +# Ejecutar las siguientes tres lineas, para generar un archivo de ejemplo y practicar el comando uniq +truncate --size 0 syslog-alumnos.txt +seq 5 | xargs -I {} sh -c 'echo "$(date +%T), alumno 00{}, online";' | tee --append syslog-alumnos.txt +seq 5 | xargs -I {} sh -c 'echo "$(date +%T), alumno 00{}, online"; sleep 1;' | tee --append syslog-alumnos.txt + +# Contar la cantidad de veces que se repite una linea + mostrar cada linea una única vez +# +# - comando sort opción --key=2, ordenamos por la 2º columna +# - es necesario previo a usar uniq, ordenar si las lineas del archivo si sabemos que NO está ordenado por algún criterio +# - opción --count, agrega un prefijo con el número de veces que se repita +sort --key=2 syslog-alumnos.txt | uniq --count +sort -k 2 syslog-alumnos.txt | uniq -c + +# Mostrar columnas específicas de un archivo delimitado por el símbolo coma + contar las veces que se repiten las lineas +# (previo a usar uniq -c, ordenamos por la 1º columna caso contrario no agrupará correctamente) +cut alumnos.txt --delimiter=',' --fields=2,3 | sort --key=1 | uniq --count +cut alumnos.txt -d ',' -f 2,3 | sort -k 1 | uniq -c + +# Mostrar las lineas que se repiten (1 vez) y las que NO se repiten +sort syslog-alumnos.txt | uniq + +# Mostrar las lineas que se repiten (1 vez) y las que NO se repiten +# PERO.. ignorar las mayúsculas y minúsculas al comparar entre las lineas +sort syslog-alumnos.txt | uniq --ignore-case +sort syslog-alumnos.txt | uniq -i + +# Mostrar las lineas que se repiten (1 vez) y las que NO se repiten, +# PERO ignorar la 2º columna al comparar entre lineas repetidas +sort syslog-alumnos.txt | uniq --skip-fields=2 +sort syslog-alumnos.txt | uniq -f 2 + +# Mostrar sólo las lineas que NO se repiten +# - comando sort opción --key=1, ordenamos por la 1º columna (es necesario si sabemos que el archivo no está ordenado) +sort --key=1 syslog-alumnos.txt | uniq --unique +sort -k 1 syslog-alumnos.txt | uniq -u + +# Mostrar sólo las lineas que se repiten +sort --key=1 syslog-alumnos.txt | uniq --repeated +sort -k 1 syslog-alumnos.txt | uniq -d diff --git a/doc/linux-shell/commands/watch-tail.sh b/doc/linux-shell/commands/watch-tail.sh new file mode 100644 index 0000000..2419fee --- /dev/null +++ b/doc/linux-shell/commands/watch-tail.sh @@ -0,0 +1,8 @@ +## CATEGORIA: operaciones con archivos +## DESCRIPCION: observar cambios de estado en archivos y directorios + +# observar cambios en un directorio (nuevos archivos, carpetas, ..) +watch ls videos-favoritos/ + +# observar cambios en un archivo específico (si es truncado, cambios en el contenido, ..) +tail -f articulos/noticias.txt diff --git a/doc/linux-shell/commands/whatis.sh b/doc/linux-shell/commands/whatis.sh new file mode 100644 index 0000000..d12df63 --- /dev/null +++ b/doc/linux-shell/commands/whatis.sh @@ -0,0 +1,11 @@ +## CATEGORIA: documentación de comandos +## DESCRIPCION: obtiene una descripción corta del manual page (man) + +# obtener la descripción corta de un comando +whatis ls + +# es equivalente a usar `whatis` +man -f ls + +# obtener la descripción corta de varios comandos +whatis ls cp rm mv diff --git a/doc/linux-shell/commands/whiptail.sh b/doc/linux-shell/commands/whiptail.sh new file mode 100644 index 0000000..bf0b686 --- /dev/null +++ b/doc/linux-shell/commands/whiptail.sh @@ -0,0 +1,40 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# Cuadro de diálogo para notificar un mensaje al usuario +# +# - timeout: finaliza el proceso whiptail luego del tiempo indicado (en éste ejemplo 10 segundos) +# - reset: inicializa la terminal, la deja en un estado anterior estable (al finalizar whiptail, la pantalla se bugea y quedará inutilizable) +# - clear: limpia la terminal (no es lo mismo que reset, no resuelve el bug que genera en la pantalla la finalización de whiptail) +timeout 10 whiptail --msgbox "El servidor se apagará en 10 segundos" 10 50; +reset; clear + +# Cuadro de diálogo del tipo Aceptar/Cancelar +# +# - son opcionales las opciones --yes-button y --no-button +# - 2>&1 redirecciona STDERR al STDOUT, porque whiptail escribe los resultados en STDERR (fd 2) y muestra la caja de diálogo por STDOUT (fd 1) +# - 1>/dev/tty redirecciona el STDOUT (fd 1) a la terminal activa (en uso), es opcional indicar el fd 1 porque el operador de redirección > lo utiliza por default +# - $? almacena el Estado de Salida del último comando ejecutado en la terminal (con valor 0 cero si tuvo éxito, distinto de cero si falló) +whiptail --title "Borrar archivos" --yesno "Desea confirmar la acción?" 10 50 --yes-button "Confirmar" --no-button "Cancelar" 2>&1 1>/dev/tty \ + && test $? -eq 0 && echo "Borrando archivos.." || echo "ok, decidiste no borrar los archivos" + +# Cuadro de diálogo que solicita escribir datos por STDIN (fd 0, teclado) +# +# - el último parámetro de whiptail con --inputbox es opcional, será el valor por default que sugerirá escribir +# - el operador pipe (|) redirecciona el STDOUT (que escribió whiptail) como STDIN al comando xargs +# - el comando xargs -I %, le define el símbolo % al input que le redireccionado por el operador pipe +# - 3>&1 2>&1 2>&3 tiene mismo objetivo que 2>&1 1>/dev/tty, pero creando un nuevo File Descriptor (3) que referencia al STDOUT (fd 1) y al que redireccionará el STDERR (fd 2) +whiptail --title "Crear usuario" --inputbox "Escriba el nombre de usuario" 10 50 "root" 3>&1 1>&2 2>&3 \ + | xargs -I % echo "Hola %" + +# alternativa al whiptail --inputbox (pero sin la interfáz de whiptail) +read -p "Escriba el nombre de usuario que desea crear: " NOMBRE + +# Cuadro de diálogo con un menú de opciones +# +# - luego del alto (10) y ancho (50) de la caja de diálogo, indicamos el alto (2) del menú +# - cada opción necesita dos valores de la forma: "nombre" "descripcion" +whiptail --title "Cambiar de Shell" --menu "Seleccione una opción" 10 50 2 \ "Bash" "(Bourne Again Shell)" \ "Zsh" "(Z Shell)" 2>&1 1>/dev/tty \ + | xargs -I % echo "Cambiando a %" + + diff --git a/doc/linux-shell/commands/who.sh b/doc/linux-shell/commands/who.sh new file mode 100644 index 0000000..e584adb --- /dev/null +++ b/doc/linux-shell/commands/who.sh @@ -0,0 +1,26 @@ +## CATEGORIA: información usuarios del sistema +## DESCRIPCION: mostrar información de los usuarios logeados y que comandos ejecutan +## OBSERVACIONES: Agrupamos los comandos w, who, whoami, users + +# Mostrar el nombre de usuario actual (Who am I?) +whoami + +# Mostrar información de (who) quienes están logeados +who + +# Mostrar que están haciendo los usuarios logeados +# - que comandos están ejecutando (Ej. /bin/bash /bin/sh xfce4-session) +# - muestra métricas del sistema operativo (tiempo activo, tiempo inactivo, ..) +w + +# Mostrar información de un usuario específico (Ej. jelou) +# - Cada subshell en ejecución (Ej. pts/0 pts/1 pts/2 ..) +# - Que comando está ejecutando en cada subshell (Ej. /bin/bash xfce4-session ...) +w jelou + +# Contar la cantidad de usuarios activos (logeados) y mostrar su nombre de usuario +who --count +who -c + +# Imprimir los nombres de usuarios activos (logeados) +users diff --git a/doc/linux-shell/commands/xargs.sh b/doc/linux-shell/commands/xargs.sh new file mode 100644 index 0000000..5658079 --- /dev/null +++ b/doc/linux-shell/commands/xargs.sh @@ -0,0 +1,21 @@ +## CATEGORIA: clasificar comando +## DESCRIPCION: describir comando + +# Imprimir por pantalla el comando y el parámetro que recibió de xargs +echo "libros" | xargs --verbose mkdir +echo "libros" | xargs -t mkdir + +# Pasar un parámetro a varios comandos +# +# - la opción -I de xargs, permite asignarle un símbolo al parámetro redireccionado por el operador pipe a xargs +echo "libros" | xargs -I % sh -c "mkdir %; touch %" + +# Buscar archivos por su extensión y moverlos a otra ruta +# +# - la opción --verbose de xargs, hará que se imprima (utilizando el comando echo) varias operaciones mv (de cada archivo que encontró el comando find) +find ./documentos -type f -name "*.txt" \ + | xargs --verbose -I % mv % ./backup + +# alternativas para copiar todos los archivos de texto plano a otro directorio +cp --verbose documentos/*.txt backup +rsync --verbose documentos/*.txt backup diff --git a/doc/linux-shell/shortcuts/.template b/doc/linux-shell/shortcuts/.template new file mode 100644 index 0000000..d53bca2 --- /dev/null +++ b/doc/linux-shell/shortcuts/.template @@ -0,0 +1,11 @@ +#+NAME: atajos +| Atajo | Descripción | +|------------+-----------------| +| Alt + F4 | Cerrar programa | +| Ctrl Alt F | Abrir terminal | + +#+NAME: otros-atajos +| Atajo | Descripción | +|------------+-----------------| +| Alt + F4 | Cerrar programa | +| Ctrl Alt F | Abrir terminal | \ No newline at end of file diff --git a/doc/linux-shell/shortcuts/fish.org b/doc/linux-shell/shortcuts/fish.org new file mode 100644 index 0000000..3360614 --- /dev/null +++ b/doc/linux-shell/shortcuts/fish.org @@ -0,0 +1,5 @@ +#+NAME: Atajos Simples +| Atajo | Descripción | +|--------------------------+--------------------------------------------| +| Alt LeftArrow/RightArrow | Moverse entre los directorios padres/hijos | + diff --git a/doc/linux-shell/shortcuts/screen.org b/doc/linux-shell/shortcuts/screen.org new file mode 100644 index 0000000..d0f3c23 --- /dev/null +++ b/doc/linux-shell/shortcuts/screen.org @@ -0,0 +1,21 @@ +#+NAME: Atajos Simples +| Atajo | Descripción | +|----------+-----------------------------------------------------------------| +| Ctrl a : | Permite escribir el nombre del atajo similar a editor vim | +| Ctrl a ? | Muestra todos los atajos | +| Ctrl a d | Desvincular la sesión actual | +| Ctrl a k | Matar la sesión actual | +| Ctrl a x | Bloquea la sesión actual (requiere clave de la sesión de linux) | +| Ctrl a \ | Cierra todas las ventanas de la sesión actual | + +#+NAME:Atajos si queremos manejar múltiples ventanas en la misma terminal +| Atajo | Descripción | +|------------+----------------------------------------------------------------| +| Ctrl a | Dividir la terminal verticalmente | +| Ctrl a S | Dividir la terminal horizontalmente | +| Ctrl a c | Crea una nueva ventana (útil si dividimos la terminal) | +| Ctrl a " | Lista de ventanas para seleccionar | +| Ctrl a w | Menciona las ventanas creadas la parte inferior de la terminal | +| Ctrl a tab | Selecciona la siguiente ventana de la sesión | +| Ctrl a 0 | Selecciona la ventana 0 de la sesión | +| Ctrl a 1 | Selecciona la ventana 1 de la sesión | diff --git a/doc/notes/tty-pts.org b/doc/notes/tty-pts.org new file mode 100644 index 0000000..ace0c8d --- /dev/null +++ b/doc/notes/tty-pts.org @@ -0,0 +1,54 @@ +#+CATEGORIA: TTY y PTS +#+DESCRIPCION: pendiente +* Shortcuts +** Tabla Comparativa + | Shortcut | Descripción | origen | + |------------------+-----------------------------------------------------------------------------------+-------------------------------| + | Alt + Ctrl + T | abrir un Emulador de Terminal | desde una sesión X | + | Alt + Ctrl + FN | abrir una Consola Virtual en pantalla completa (/siendo N un entero entre 1 y 7/) | desde una sesión X | + | Ctrl + Shift + T | abrir una Pseudo Terminal (pts) | desde un Emulador de Terminal | + | Alt + FN | abrir una Consola Virtual en pantalla completa (/siendo N un entero entre 1 y 7/) | desde una Consola Virtual | + |------------------+-----------------------------------------------------------------------------------+-------------------------------| +** Sesión X + - dentro de una *Sesión X*, podemos abrimos un *Emulador de Terminal* +** Emulador de Terminal (Konsole, xterm, Gnome Terminal, ..) + - desde en un *Emulador de Terminal*, creamos una ó varias (pts) *Pseudo Terminales* (pts1, pts2, ...) +** Pseudo-terminales (/dev/pts/1, /dev/pts/2, ...) + - son controladas por el *Emulador de Terminal* que las creó +** Consolas Virtuales (/dev/tty1, /dev/tty2, ..) + - si presionamos ~Alt + F7~ "por lo general" volvemos a la *Sesión X* (el Graphical Desktop, Escritorio con Interfáz Gráfica) +* Stdin, Stdout, Stderr + - son archivos especiales (Enlaces Simbólicos) que apuntan a los *File Descriptor* (archivos) 0, 1, 2 + - podemos comprobar lo anterior con ~ls -l /dev/{fd,stdin,stdout,stderr}~ +* File Descriptors (0, 1, 2) + - son archivos especiales (Enlaces Simbólicos) que apuntan a la (PTS) Pseudoterminal en uso + - podemos comprobrar lo anterior con ~ls -l /dev/fd/{0,1,2}~ +* Redireccionar a stdout, file descriptor 0, Consola Virtual (tty), Pseudo Terminal activa (pts) + - Si usamos el operador de redirección (>) el resultado será el mismo para los siguientes + + #+BEGIN_SRC shell + # ejemplo con el stdout + echo "hola" > /dev/stdout + + # ejemplo con el file descriptor 1 + echo "hola" > /proc/self/fd/1 + + # ejemplo con la consola virtual (tty) + echo "hola" > /dev/tty + + # ejemplo con la pseudo terminal activa (pts) + echo "hola" > $(tty) + echo "hola" > `tty` + #+END_SRC +* Pseudo Terminales (pts) + - *(pts)* refiere a *Pseudo TTY Slave* (Pseudo terminal Esclavo) y son utilizados por las Shell (Ej. Bash, Zsh, ..) + - *(ptm)* refiere a *Pseudo TTY Master* (Pseudo terminal Maestro) + - son *archivos de Dispositivos de Caracteres* tanto los ~/dev/tty1~, ~/dev/tty2~, .. como ~/dev/pts/0~, ~/dev/pts/1~, .. + - podemos ver que es son un *tipo de archivo de Dispositivo de Caracteres* con + - para ver las tty ~ls -l /dev/tty{0,1,2,3,4,5,6,7}~ + - para ver las pts ~ls -l /dev/pts/{0,1,2,3}~ (recordemos que creań desde un Emulador de Terminal, Ej. Konsole) +* Pseudo TTY Multiplexor Maestro (/dev/ptmx) + - si un *Emulador de Terminal* lo abre, éste devuelve + - un *File Descriptor de un (ptm)* + - un *File Descriptor de un (pts)* + - podemos ver que es un *tipo de archivo de Dispositivo de Caracteres* con ~ls -l /dev/ptmx~ diff --git a/scripts/edit-popup.sh b/scripts/edit-popup.sh new file mode 100755 index 0000000..6c4f72d --- /dev/null +++ b/scripts/edit-popup.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# $1: primer parámetro, recibe el tipo de editor (Ej. vim, neovim, nano) +# $2: segundo parámetro, recibe la ruta para editar los comandos del comando en formato .sh +# $3: tercer parámetro, recibe la ruta para editar los shortcuts del comando en formato .org +read -p "Si desea editar los comandos escriba sin los paréntesis (c) y para shortcuts (s): " choice +case "$choice" in + c ) $1 $2;; + s ) $1 $3;; + * ) echo no && exit 1 +esac diff --git a/utils/menus.mk b/utils/menus.mk new file mode 100644 index 0000000..4f6bf87 --- /dev/null +++ b/utils/menus.mk @@ -0,0 +1,81 @@ +# TODO: refactor, lógica repetida +BOX_CONFIRM_INSTALL=whiptail \ + --title "Instalar Aplicación $(APP_NAME)" \ + --yesno "¿Desea confirmar acción?" 0 0 \ + --no-button "Cancelar" --yes-button "Confirmar" + +BOX_CONFIRM_UNINSTALL=whiptail \ + --title "Desinstalar Aplicación $(APP_NAME)" \ + --yesno "¿Está seguro de confirmar acción?" 0 0 \ + --no-button "Cancelar" --yes-button "Confirmar" + +MENU_SHOW_NOTES=whiptail \ + --title "Mostrar documentación en Notas" \ + --menu "Elegir una opción" 0 0 5 $(NOTES_LIST) + +# TODO: refactor, lógica repetida +MENU_EDIT_LINUX_COMMANDS=whiptail \ + --title "Editar documentación de Linux" \ + --menu "Elegir una opción" 0 0 5 $(LINUX_COMMANDS_LIST) + +MENU_EDIT_LINUX_SHORTCUTS=whiptail \ + --title "Editar documentación de Linux" \ + --menu "Elegir una opción" 0 0 5 $(LINUX_SHORTCUTS_LIST) + +MENU_EDIT_APPS_COMMANDS=whiptail \ + --title "Editar documentación de una Aplicación" \ + --menu "Elegir una opción" 0 0 5 $(APPS_COMMANDS_LIST) + +MENU_EDIT_APPS_SHORTCUTS=whiptail \ + --title "Editar documentación de una Aplicación" \ + --menu "Elegir una opción" 0 0 5 $(APPS_SHORTCUTS_LIST) + +MENU_CREATE_DOC=whiptail --title "Crear documentación" \ + --menu "Elegir una opción" 30 80 5 \ + "linux-create-doc" "Documentación de Linux" \ + "app-create-doc" "Documentación de una Aplicación" + +MENU_EDIT_DOC=whiptail --title "Editar documentación" \ + --menu "Elegir una opción" 30 80 5 \ + "linux-edit-commands" "Comandos de Linux" \ + "linux-edit-shortcuts" "Shortcuts de Linux" \ + "app-edit-commands" "Comandos de una Aplicación" \ + "app-edit-shortcuts" "Shortcutsde una Aplicación" + +# Notas: +# 1. Ojo! Si usamos ésta MACRO como una orden de una regla, no encontrará los targets en el Makefile para crearlos +# 2. Usarla para pasarla de parámetro a algún comando de linux +# TODO: refactor, lógica repetida +SHORTCUTS_LINUX_FORMAT=$(shell echo $(SHORTCUTS_LINUX) | sed -E 's/([[:alpha:]]+) /\1|/g') +SHORTCUTS_APPS_FORMAT=$(shell echo $(SHORTCUTS_APPS) | sed -E 's/([[:alpha:]]+) /\1|/g') + +# TODO: refactor, lógica repetida +LINUX_COMMANDS_LIST=$(shell cat $(DOC_LINUX).txt \ + | nawk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/(.+)::(.+)/"\1" "\2" \\/g' \ + | tr '\\' '\n') + +# Notas: +# 1. Si usamos el operador != en vez de la función $(shell ) no cumplirá su propósito el slash invertido +# 2. En véz de borrar lineas con el comando sed y su opción /d, se prefirió filtrar filas con awk que también permite patrones (más fácil) +LINUX_SHORTCUTS_LIST=$(shell cat $(DOC_LINUX).txt \ + | awk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/([[:alpha:]]+)::(.+)/\"\1\" \"\2\"\\/g' \ + | awk '/$(SHORTCUTS_LINUX_FORMAT)/' \ + | tr '\\' '\n') + +APPS_COMMANDS_LIST=$(shell cat $(DOC_APPS).txt \ + | nawk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/(.+)::(.+)/"\1" "\2" \\/g'\ + | tr '\\' '\n') + +APPS_SHORTCUTS_LIST=$(shell cat $(DOC_APPS).txt \ + | awk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/([[:alpha:]]+)::(.+)/\"\1\" \"\2\"\\/g' \ + | awk '/$(SHORTCUTS_APPS_FORMAT)/' \ + | tr '\\' '\n') + +NOTES_LIST=$(shell cat $(DOC_NOTES).txt \ + | nawk -F '|' '{print $$1 "::" $$2}' \ + | sed -E 's/(.+)::(.+)/"\1" "\2" \\/g' \ + | tr '\\' '\n') diff --git a/utils/unix-utils.mk b/utils/unix-utils.mk new file mode 100644 index 0000000..af6557d --- /dev/null +++ b/utils/unix-utils.mk @@ -0,0 +1,24 @@ +BAT=bat --line-range $(NUMBER_LINE_BEGIN_DOCUMENTATION): +EDITOR_NOTE=bat --line-range $(NUMBER_LINE_BEGIN_DOC_NOTES): + +NAWK_HEADERS=nawk 'BEGIN{print "Comando | Categoría | Descripción"} {print $$0}' | column -t -s "|" + +# en GNU Make debemos escapar el $ que utiliza awk para los parámetros por eso $$1 $$2 en vez de $1 ó $2, +# para que lo tome como un caracter y no lo tome una referencia a una macro de GNU Make +NAWK_ORDER_FIELDS=nawk -F '|' '{print $$1 " | " tolower($$2) " | " toupper(substr($$3,1,1)) substr($$3,2)}' + +TRUNCATE_CLEAR_CONTENT=truncate -s 0 + +# luego es utilizado al listar los comandos por la segunda columna (categoria) +# Ej. cat comandos.txt | sort -t "|" -k 2 +SORT_BY_COLUMN = sort -t "|" -k + +COPY_NOT_OVERWRITE=rsync --ignore-existing +# alternativa al rsync --ignore-existing es cp --no-clobber + +# - el $? NO es una macro de GNU Make, es propio de linux y guarda el Estado de Salida luego de ejecutar un comando de linux (programas) +EXIT_STATUS=$(shell echo $$?) + +# - el valor 0 indíca que el comando de linux se ejecutó con éxito +# (se le pasaron opciones que posee, parámetros válidos como rutas, ...) +EXIT_STATUS_SUCCESS=0 diff --git a/utils/update-bash-aliases b/utils/update-bash-aliases new file mode 100755 index 0000000..4f12859 --- /dev/null +++ b/utils/update-bash-aliases @@ -0,0 +1,4 @@ +#!/bin/env bash +echo "Actualizando los alias de bash.." +source ~/.bash_aliases +exec bash "$@" diff --git a/utils/utils.mk b/utils/utils.mk new file mode 100644 index 0000000..560c3c5 --- /dev/null +++ b/utils/utils.mk @@ -0,0 +1,18 @@ +CURRENT_DIRECTORY=$(shell pwd) + +APP_AUTHOR=neverkas +APP_NAME=command-helper + +BASH_ALIAS_SYMBOL= ? +BASH_ALIASES_FILE=~/.bash_aliases + +BASH_ALIAS="alias $(BASH_ALIAS_SYMBOL)='make --no-print-directory -C $(CURRENT_DIRECTORY)' \ + CURRENT_TTY_PATH=$$(pwd) \ + APP_AUTHOR=$(APP_AUTHOR)" + +# alias ?='make --no-print-directory -C /home/jelou/Documents/git/manu-makefiles/command-helper CURRENT_TTY_PATH=$(pwd)' +BASH_ALIAS_ESCAPE_SLASH=$(subst /,\/,$(BASH_ALIAS)) + +POPUP_EDIT = sh ./scripts/edit-popup.sh $(TEXT_EDITOR) + +APP_INSTALLED=$(shell grep -q "^alias ?='make.*APP_AUTHOR=neverkas" ~/.bash_aliases && echo true)