Discriminar columnas desde el terminal de linux

sed y awk

Extracto

El comando ‘ls -la‘ nos produce siempre nueve columnas. A veces, sobre todo cuando queremos redirigir el resultado a un fichero, puede que nos estén sobrando información, tan solo queremos alguna de las columnas. Os presento el comando awk de Linux.

@pedroruizhidalg―

Descripción

Cuando ejecutamos ‘ls -la’, yo tengo un alias al que le llamo ‘ll’, nos produce algo así como lo siguiente:

$ ls -la
total 152
drwxrwxr-x  2 pedro pedro  4096 mar  1 13:43 .
drwx-----x 79 pedro pedro 20480 feb 27 20:18 ..
-rwxrwxr-x  1 pedro pedro   640 ene 21 18:17 buscar
-rwxrwxr-x  1 pedro pedro   352 feb  5 11:35 dni
-rwxrwxr-x  1 pedro pedro  3276 feb 12 14:43 l
-rwxrwxr-x  1 pedro pedro  2758 feb 18 11:37 lin
-rwxrwxr-x  1 pedro pedro  1326 feb 21 13:35 list.dir
-rwxrwxr-x  1 pedro pedro  1318 feb 28 12:33 list.files
-rwxrwxr-x  1 pedro pedro   388 feb  7 20:43 prueba_substring
-rwxrwxr-x  1 pedro pedro   185 feb  8 13:15 qqq
-rwxrwxr-x  1 pedro pedro    21 ene 21 17:20 script1
-rwxrwxr-x  1 pedro pedro    49 mar  1 13:41 tawk
$

Sin embargo yo puedo querer filtrar sólo la columna del nombre de usuario, que si nos damos cuenta es la cuarta columna.

Ejecución

Para ello crearemos una tubería tras el comando de listado para que le entrege los datos obtenidos a awk, indicándole que muestre tan solo la columna número 4. Así:

 

$ ls -la | awk '{print $4}'

pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
pedro
$

Epílogo

 

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

 

 #aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Listar elegantemente sólo los ficheros de un directorio

logo bash Bourne again shell

Extracto

Linux es un sistema maravilloso, pero con una sintaxis confusa, llena de parámetros. Tengo la costumbre de hacerme mis propios comandos, o bien, recrear aquéllos que uso de manera habitual con mi propia sintaxis. Es esta ocasión vamos a mejorar la salida del comando find para obtener una lista exclusivamente de los archivos que hay en un directorio dado.

@pedroruizhidalg― En esta ocasión vamos a usar PHP como motor de órdenes en BASH ya que la potencia de ejecución (y sintaxis) de BASH, aunque hay que conocerlas, no tenemos por qué «conformarnos» con ella. Aunque este script puede ser un poco farragoso, he querido mostrarlo precisamente porque en él convierto una lista de archivos en un array, opero con ese array, lo descompongo para cambiar de color y lo presento por pantalla. Además incluyo parámetros de ayuda y autor.

 

Descripción

La primera linea, llamada shebang, se usa para informar al sistema operativo que queremos usar PHP como lenguaje en el termina. Más información aquí. En realidad le pedimos a /usr/bin/env que nos proporcione la ruta de PHP.

Tras esto viene la declaración de inicio de sintaxis PHP, y tras los comentarios iniciales de rigor, se declaran las constantes que se usarán a lo largo del programa. He declarado más de las necesarias, para que podáis jugar con ellas si así os apetece.

Cuando PHP es usado como un programa de script, los argumentos (información que le pasamos desde la línea de comandos) vienen empaquetados en el array llamado $argv. Siempre, el elemento cero de este array es el nombre del programa. La variable $dir cuenta el número de argumentos, si es dos, significa que existe el argumento cero, ya descrito, y nos están proporcionando otro, que será la dirección del directorio a listar. En otras palabras, si me están proporcionando una dirección de directorio la incluyo con $argv[1], en caso contrario lo convierto en “.”, que significa literalmente «este directorio».

La siguiente variable $exec, contiene la orden find con los parámetros del directorio a listar $dir. Pero abundemos más en la sintaxis de ‘find [directorio] -maxdepth 1 -type f‘. Estamos indicando que queremos que encuentre en el directorio indicado con una profundidad (de subdirectorios) de 1, en otras palabras, sólo en ese directorio, prescindiendo de los subdirectorios que pudiera contener; los elementos tipo “f”: o sea, los ficheros. Para encontrar los subdirectorios prescindiendo de los archivos la orden sería ‘find [directorio] -maxdepth 1 -type d‘.

Con estas órdenes ya bastaría, pero quiero resaltar en negrita, sí, en el terminal de Linux, el nombre de los archivos. Realmente por eso realicé este script que os muestro.

Si el argumento que me han pasado es “-h” entiendo que quieren ver la ayuda, la muestro y salgo indicando error 0, que significa que no hubieron errores. Si el argumento es “-a” me están pidiendo el autor, lo muestro y salgo indicando error 0.

La orden exec en PHP ejecuta una orden de sistema operativo, tiene tres parámetros: el primero es la orden en sí. El segundo es un array con lo que nos devuelve el sistema tras la ejecución si hubiera tenido éxito. El tercero es el número de error que se produjo: cero si no lo hubo.

Por tanto si la variable $retval es cero, sé que tengo información que mostrar de la variable $output, porque no hubieron errores. A cada elemento lo someto a la función to_bold y lo muestro por pantalla.

Llevo cada valor de $output a to_bold(), y aquí lo que hago es descomponer cada elemento individual, buscando el carácter “/”, le doy la vuelta al string, porque así el nombre del archivo siempre estará a la izquierda de un carácter “/” (se me acaba de ocurrir que podría haber contado hacia atrás, pero eso es un lío). Lo retorno formateado y con las constantes que definimos, y muestro “salida sin errores”.

#!/usr/bin/env php

<?php
 /***
 * Muestra 'find . -maxdepth 1 -type f' 
 * Es decir: muestra exclusivamente los archivos de un directorio
 * 
 * @author: Pedro Ruiz Hidalgo, @pedroruizhidalg
 * @date: February 21 2017
 * 
 ***/
 define("RT","\n");
 define('TAB',"\t");
 define('RED',"\033[31m");
 define('BOLD',"\033[1m");
 define('NC',"\033[0m"); // ningún color
 define('NAME',$arg[0]);

 $dir = (count($argv)==2) ? $argv[1] : '.';
 $exec = "find $dir -maxdepth 1 -type f";
 
 if($dir=='-h')
 {
 echo RT.TAB.'help'.RT;
 echo RT.TAB.NAME.BOLD.' [DIRECTORIO]'.NC.RT.RT;
 exit(0);
 }

 if($dir=='-a')
 {
 echo RT.TAB.'Autor'.RT;
 echo RT.TAB.NAME.BOLD.' Pedro Ruiz Hidalgo (c) 2017'.NC.RT.RT;
 exit(0);
 }

 exec($exec,$output,$retval);

 if($retval==0)
 {
 foreach ($output as $value) {
 echo to_bold($value);
 }
 echo RT.BOLD.'Salida sin errores'.NC.RT;
 } else { 
 echo RT.RED."error resultado $retval".NC.RT;
 }

 function to_bold($value)
 {
 $pos="";
 $value=strrev($value);
 $pos=strpos($value,'/');
 $path=strrev(substr($value, $pos));
 return $path.$val=BOLD.strrev(substr($value, 0,$pos)).NC.RT;
 }

Ejecución

Guardar el archivo con el nombre “list.files”. Le damos permisos de ejecución con “chmod +x list.files”.

$ list.files 

./.directory
./tres60.tar.gz
./dlreves.tar.gz
./phpinfo.php
./bt.zip
./bootstrap.tar.gz

Salida sin errores
$

Debería mostraros algo así. Obviamente con vuestro contenido, 🙂

Epílogo

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

 

 #aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Validación “edit unique” en CodeIgniter

Extracto

Es cierto, CodeIniger, tiene muy buen sistema de validaciones, aunque le falten algunas tan tontas como un validador de fechas, y uno que antes de realizar un update en la base de datos compruebe que los campos que hemos declarado como claves UNIQUE sigan siéndolo con los nuevos datos que estamos modificando.

@pedroruizhidalg―La situación es la siguiente: tengo una tabla a la que llamo kanban, cuyo campo kanban_name he descrito como único. Así:

class Migration_Install_kanban extends CI_Migration {

        function up()
        {
            $this->db->query('SET foreign_key_checks=0');
        	$this->dbforge->drop_table('kanban',TRUE);

        	$this->dbforge->add_field(array(
        		'id'	=>	array(
        				'type'				=>	'MEDIUMINT',
        				'constraint'		=>	'8',
        				'unsigned'			=>	TRUE,
        				'auto_increment'	=>	TRUE,
        		),
        		'kanban_name'	=> array(
        				'type'				=>	'VARCHAR',
        				'constraint'		=>	'120',
        				'NOT NULL'			=>	TRUE
        			),
        		'kanban_description'	=> array(
        				'type'				=>	'MEDIUMBLOB'
        			),

                'kanban_datestart'   =>  array(
                        'type'              =>  'DATETIME'
                ),

                'kanban_datefinish'   =>  array(
                        'type'              =>  'DATETIME'
                ),

        		'kanban_datecreation'	=>	array(
        				'type'				=>	'DATETIME'
        		),

                'kanban_idcreator'  =>  array(
                        'type'              =>  'MEDIUMINT',
                        'constraint'        =>  '8',
                        'unsigned'          =>  TRUE,
                ),
                
        		'kanban_ipcreation'		=>	array(
        				'type'				=>	'CHAR',
        				'constraint'		=>	'15'
        		),
                'kanban_datemodification'   =>  array(
                        'type'              =>  'DATETIME'
                ),
                'kanban_idmodification'	=>      array(
                                'type'                  =>      'MEDIUMINT',
                                'constraint'            =>      '8',
                                'unsigned'              =>      TRUE,
                ),
                'kanban_deleted'       =>       array(
                                'type'                  =>      'enum',
                                'constraint'            =>      array('y','n'),
                                'DEFAULT'               =>      'n'
                )
        	));

        	$this->dbforge->add_key('id',TRUE);
        	$this->dbforge->create_table('kanban');
        	$this->db->query('ALTER TABLE kanban ADD FOREIGN KEY(kanban_idcreator) REFERENCES users(id) ON UPDATE CASCADE ON DELETE RESTRICT');
        	$this->db->query('ALTER TABLE kanban ADD CONSTRAINT kanban_name UNIQUE (kanban_name)');
            $this->db->query('SET foreign_key_checks=1');
		}

		function out()
		{
			$this->db->query('SET foreign_key_checks=0');
            $this->dbforge->drop_table('kanban', TRUE);
            $this->db->query('SET foreign_key_checks=1');
		}
}

Descripción

Cuando edito un registro de la tabla kanban necesito seguir manteniendo la unicidad (exclusividad) de valor de campo kanban_name. Me explico, como es valor de este campo no se puede repetir, si el usuario introduce un valor ya existente produciría un error la base de datos debido a la restricción de la clave de tipo UNIQUE, como puede verse arriba. CodeIgniter no soluciona de forma nativa esta circunstancia de ninguna manera.

Empecemos.

Ejecución

Creo application/libraries/MY_Form_validation.php con el siguiente código:

<?php

class MY_Form_validation extends CI_Form_validation{

    public function edit_unique($str, $field)
    {
        sscanf($field, '%[^.].%[^.].%[^.]', $table, $field, $id);
        return isset($this->CI->db)
            ? ($this->CI->db->limit(1)->get_where($table, array($field => $str, 'id !=' => $id))->num_rows() === 0)
            : FALSE;
    }

}

En mi controlador coloco el siguiente código:

 

private function validation_rules($id)
    {
        $validation     =    array(
            array(
                'field'     =>    'kanban_activity_name',
                'label'        =>    $this->lang->line('kanban_activity_name'),
                'rules'        =>    "required|trim|max_length[120]|edit_unique[kanban.kanban_name.$id.]",
                'errors'    =>     array(
                    'edit_unique'    =>    lang('kanban_unique_name')
                    )
            ),
            array(
                'field'     =>    'kanban_description',
                'label'        =>    $this->lang->line('kanban_description'),
                'rules'        =>    'required|trim|min_length[5]|max_length[16777215]',
            ),
            array(
                'field'     =>    'kanban_datestart',
                'label'        =>    $this->lang->line('kanban_date_start'),
                'rules'        =>    'required|callback_date_valid',
                'errors'    =>     array(
                        'date_valid'=> sprintf(lang('kanban_date_bad_format'),set_value('kanban_datestart')),
                    )
            ),
            array(
                'field'     =>    'kanban_datefinish',
                'label'        =>    $this->lang->line('kanban_date_end'),
                'rules'        =>    'required|callback_date_valid|callback_date_after',
                'errors'    =>     array(
                        'date_valid'=> sprintf(lang('kanban_date_bad_format'),set_value('kanban_datefinish')),
                        'date_after'=> sprintf(lang('kanban_date_bad_after'),set_value('kanban_datestart'))
                    )
            )
        );
        $this->validation->set_rules($validation);
    }

 

Como puedes ver hay un argumento obligatorio en la función validation_rules, a partir de ahora lo llamo así:

function index($idkanban)
{
    $this->validation_rules($idkanban);
.../...
}

 

Es decir paso como argumento validation_rules el id del registro que estoy modificando. Es todo.

Epílogo

Como podrás observar el elemento rules del array de kanban_activity_name lo paso entre comillas dobles para que pueda interpretar el valor del argumento id dentro de la cadena de reglas.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude
exlibri del autor
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Trabajar con MY_Controller de CodeIgniter

Extracto

Reemplazar las librerías nativas de CI con nuestras propias versiones. Asignando un nombre a los archivos de clase idéntico a una librería nativa causaremos que CI los utilice en lugar de las clases nativas. Esta característica se invoca de la forma más elemental: llamar a la librería igual que su nombre nativo de CI. Por ejemplo para reemplazar con nuestro propio código a la librería nativa de Email tan solo tenemos que crear el archivo application/libraries/Email.php y declarar su clase como:

class CI_Email{
// aquí tu código ///
}

@pedroruizhidalg―Hay que tener en cuenta que la mayoría de las clases empiezan con el prefijo CI, aunque no todas. Has de tener cuidado con esto. No obstante si lo que necesitamos es añadir una (o varias) funcionalidades extra a nuestras clases nativas, es más recomendable usar la extensión de las librerías nativas que andar reconstruyendo todo desde cero: reinventando la rueda.

Abreviaturas usadas

CI=CodeIgniter.

Descripción

Un ejemplo Práctico: De forma general, hay que hacer una comprobación del login y los permisos de usuario antes de ejecutar cualquier controlador. La arquitectura para esto es tan simple como potente. Lo primero que tenemos que hacer es comprobar cuál es el prefijo que tenemos declarado en application/config/config.php para el elemento subclass_prefix del array config

$config['subclass_prefix'] = 'MY_';

Generalmente, y de forma predeterminada es MY, aunque tú puedes colocar aquí cualquier nombre de prefijo de tu preferencia. Asumamos que está declarado como ‘MY’ para el ejemplo que expongo aqui.

Ejecución

Creamos un archivo llamado MY_Controller en la carpeta application/core así:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller
{
    function __construct()
    {
        parent::__construct();

        if (! $this->ion_auth->logged_in()) redirect('auth/login','refresh');

        $this->lang->load('tuarchivodelenguaje');

        $this->output->enable_profiler(TRUE); // borrar esta linea para entregar el programa

        $this->load->library('migration');

        if(!$this->migration->latest()) 
        {
              show_error($this->migration->error_string());
              exit;
        }
    }    
    
    function funcionparatodosloscontroladores()
    {
       /// aquí tu código
    }
}

Epílogo

Analicemos, pues, el código anterior de MY_Controller. Primeramente heredamos mediante parent::__construct() toda las funcionalidades de la clase Controller a este nuevo tipo de controlador. Hecho esto, comprobamos los permisos de usuario de la librería ion_auth (tú puedes usar la tuya propia u otra que te parezca mejor). Luego cargamos el archivo de lenguaje con el que estemos trabajando, obviamente en caso de necesitarlo. Activamos el profiler a true mientras estemos en fase de desarrollo, luego simplemente borramos esta única linea a la hora de entregar el producto.
En mi caso  realizo cada vez la comprobación de la versión de las migraciones aquí.

Todos los controladores, excepto los que me ayudan a hacer login, claro está, los declaro de la clase MY_Controller en vez de CI_Controller, es decir toda la estructura de controladores hereda de esta clase. De igual manera la funcion “funcionparatodosloscontroladores()” estará presente y dispuesta para todos los controladores de esta nueva clase que hemos creado. Todos los controladores heredan de este. En mi caso, aquí redefino funciones para hacer el render de las páginas a mi gusto, pues la forma nativa de CI no se adecua a mis necesidades.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude
exlibri del autor
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Gestor de copias de seguridad incrementales en Linux

Extracto

@pedroruizhidalg― Ya escribimos sobre las copias de seguridad en Linux, otra estupenda opción es rsync. Este comando (https://rsync.samba.org/) de los creadores de samba, tiene, en principio, está pensado para la sincronía remota de directorios. No obstante, su funcionalidad es muy amplia y puede ser dedicado a otros usos.

Descripción

Como primera tarea, tenemos que hacer lo posible para que nuestro sistema pueda ejecutar scripts como si de comandos se tratara. Tras esto vemos la sintaxis del bash que vamos a ejecutar para nuestras copias de seguridad incrementales.

$ cat .bin/backup

#!/bin/bash
rsync -ab --quiet --backup-dir=~/Archivos/BACKUP/ --delete --exclude=~/Archivos/BACKUP ~/ ~/Archivos/BACKUP

Vayamos por partes.

  1. La primera linea informa a linux que el scritp debe ser ejecutado con bash.
  2. La segunda es el comando rsync, que pasamos a desmenuzar.

Con la opción “a” informamos que es en modo archivo. Con “b” que estamos realizando un backup. Backup-dir informa del lugar donde vamos a realizar el backup. Delete que cualquier archivo borrado en nuestros directorios debe ser eliminado también de la copia de seguridad. Exlude indica que no incluya dicho directorio en la copia de seguridad, ya que eso crearía un bucle. Por último, ~/ indica que creo un backup de todo el home. Y lo siguiente es el destino.

Rsync soluciona un problema muy común para los administradores de redes. Aseguro que el siguiente diálogo se ha producido, por muy kafkiano que parezca:

―¿Hola? Sí, mira es que se me ha borrado un archivo, para ver si me lo puedes recuperar.
―¿Cómo se llamaba el archivo?
―No lo sé.
―¿En qué carpeta estaba?
―No me acuerdo porque la tengo que ver escrita, pero como no esta…
―¿Conoces la fecha de creación o la de modificación?
―¿Pero tú qué te crees que yo soy un informático?
―No, no me creo eso. ¿Con qué programa lo abrías?
―Con el doble click del ratón, ¡vaya pregunta más tonta me haces!

Con rsync, tenemos la oportunidad de copiar los archivos sin comprimir, y el árbol de copia de seguridad se nos queda tal cual es en el original, cosa que te puede permitir examinar todo el contenido sin necesidad descomprimir ni de maniobrar con un fichero de pongamos 500 gigas….

Ejecución

Para programar la copias de seguridad tecleamos

$ crontab -u tuusuario -i -e

Esto nos lleva a nuestro editor de la linea de comandos y programamos así. En mi caso para las 15 horas, quince minutos de todos los días.

#minuto hora diadelmes mes diadelasemana (0 es domingo)
15 15 * * * /home/pedro/.bin/backup

Lo que ejecutará el script arriba indicado que habremos guardado con el nombre de backup cada (que esté encendido el ordenador, claro :-)) a las quince horas quince minutos.

Epílogo

Para comprobar el funcionamiento del script:

ps -aux |grep backup

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude
exlibri del autor
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Copias de seguridad en Linux

Extracto

@pedroruizhidalg― Qué duda cabe, las copias de seguridad son un mal necesario en los sistemas de información tanto en los productivos, como de desarrollo e igualmente en los comerciales. El valor de una copia de seguridad es directamente proporcional a la valoración (en euros) de nuestros datos. Los informáticos que me lean entienden perfectamente qué estoy diciendo…

Descripción

Generalmente el comando que se usa en Linux para hacer copias de seguridad es tar. Si bien este comando es estupendo para crear almacenes de ficheros, es decir, tener agrupados archivos que por cualquier motivación queramos mantener agrupados (comprimidos o no), este comando deja mucho que desear en cuanto a tiempos de respuesta para copias de seguridad en sistemas de grandes volúmenes de datos. El tiempo es oro. Esto nos lleva al comando cpio.

Ejecución

La forma general de proporcionarle archivos mediante una tubería (pipe line). Lo que nos permite proporcionarle gran cantidad de archivos de una forma muy cómoda. Quiero decir, muchos archivos con muy pocas especificaciones.

Una forma de hacerlo sería suministrarle contenidos desde el comando ls.

Es algo así.

$ ls * | cpio parametros >directorio.cpio

En un caso práctico.

$ ls -w 1 -T 1 * | cpio -ocv > /home/bck.cpio

Es decir, listamos sólo los nombres de los archivos de un directorio y esto se lo “entregamos” al comando cpio que lo empaqueta en el fichero que hemos llamado bck.cpio y lo situaremos en nuesto home. La opción w 1 limita el resultado a una sola columna. La opción T 1 establece los topes de tabulación a 1 en lugar de 8 como es por defecto.

Una forma que me gusta más, de hecho es la que uso en mis sistemas es:

$ find ~/ -follow | cpio -oa | gzip -9 > ejemplo.cpio.gz

O sea, busco toda la información de mi home, esto lo “entrego” al comando cpio, que le “entrega” su proceso a gzip, para que la salida esté comprimida.

Epílogo

Una buena idea es hacer incluir esto en un script bash, para poder lanzarlo desde procesos crontab a una hora determinada. Yo lo hago así.

#!/bin/bash
_hoy=$(date +"%Y_%m_%d")
find ~/ -follow | cpio -oa | gzip -9 > "/media/Archivos/backups/$_hoy.cpio.gz"
~ $

Además con este script conseguimos que el archivo lleve como nombre la fecha en que se ha realizado.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude
exlibri del autor
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Los permisos de archivos en Linux

Extracto

@pedroruizhidalg― Cada archivo y directorio en Linux tiene asociado un conjunto de permisos de determina quiénes pueden acceder y en qué forma. Estos permisos se pueden establecer para restringir el acceso a tres entidades y de tres formas: a usted, al grupo al que perteneces y a otros ―es decir, todo el mundo―.

Descripción

Tres tipos de usuarios

Como dije en el extracto, hay tres categorías de permisos, el usuario, el grupo y otros. El propietario es quien ha creado el archivo y en Linux cualquier archivo que crees te pertenece como propietario.

Igualmente tienes perteneces a un grupo, es muy común que los usuarios se reúnan en grupos, por ejemplo: “desarrolladores”, “gráficos”, “marketing”, “dirección”, son grupos comunes en el tipo de empresas que mejor conozco.

Otros, permíteme la insistencia, es el permiso que asignamos a cualquier persona que tenga acceso a al archivo o directorio en cuestión.

permisosarchivos

Tres tipos de permisos

Existen tres tipos de permiso: Lectura, Escritura y Ejecución para cada uno de los tres tipos de usuario.

El primer tipo, Lectura, da derecho de lectura a uno de los conjuntos de usuarios. Es decir, podrías negarte a ti mismo el permiso de lectura y no el de escritura de un archivo que posees. Veamos el siguiente:

$ whoami
pedro
$ touch archivo
$ ls -l
total 0
-rw-rw-r-- 1 pedro pedro 0 oct 29 13:51 archivo
$ chmod u-r archivo
$ chmod g-r archivo 
$ chmod g-w archivo 
$ chmod o-r archivo 
$ ls -l
total 0
--w------- 1 pedro pedro 0 oct 29 13:51 archivo
$ echo "otra linea para archivo" >> archivo 
$ cat archivo 
cat: archivo: Permiso denegado

Veamos los pasos del anterior ejemplo:

  1. whoami responde a la pergunta ¿Quien soy? en Linux, es decir nos muestra el nombre de nuestro propio usuario.
  2. touch archivo crea un fichero vacío llamado archivo
  3. ls -l muestra el contenido del directorio con información ampliada. Aquí podemos comprobar cómo el propietario tiene permisos de lectura y escritura, el grupo, igualmente, lectura y escritura y otros sólo lectura.
  4. chmod u-r, elimina el permiso de lectura del usario.
  5. chmod g-r elimina el permiso de lectura del grupo.
  6. chmod g-w elimina el permiso de lectura del grupo.
  7. chmod o-r elimina el permiso de lectura de otros.
  8. ls -l, nos vuelve a mostrar los permisos. Ahora tan solo de escritura para el usuario, sin lectura.
  9. echo “otra linea para archivo” >> archivo, escribe un nuevo contenido en archivo.
  10. cat archivo muestra el archivo por la salida stándar. En esta ocasión sin éxito, ya que no tenemos permiso de lectura.

Ejecución

Por regla general yo nunca asigno los permisos a los ficheros de la forma que he indicado antes. Prefiero hacerlo con su valor numérico. Paso a explicar cómo.

$ chmod 751 archivo

Con esta orden estoy indicando lo siguiente:

  • El primer número siempre pertenece al propietario. El segundo al grupo y el tercero a otros.
  • Asigno todos los permisos al propietario.
  • Asigno al grupo los permisos de lectura y ejecución.
  • Asigno a otros el permiso de ejecución.

En la siguiente tabla os muestro el valor decimal correspondiente a su valor binario y el significado para cada grupo en concreto.

Valor binario

Valor decimal

Significado

000

0

Ningun permiso

001

1

Permiso de ejecucion

010

2

Permiso de escritura

011

3

Permiso de escritura y ejecucion

100

4

Permiso de lectura, sin escritura, sin ejecucion

101

5

Permiso de lectura y ejecucion sin escritura

110

6

Permiso de lectura y escritura sin ejecucion

111

7

Permisos de lectura, escritura y ejecucion

Epílogo

Estaré encantado de responder a vuestras cuestiones.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri del autor
exlibri del autor
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Google Inbox para gestionar mucho correo

Extracto

@pedroruizhidalg― Gestionar mucho correo se ha convertido en una tarea tan necesaria como desagradable. Seguramente os ocurrirá como a mí y recibís cientos de correos a la semana. La mayor parte de ellos totalmente inútiles, algunos de ellos interesante y pocos a los que prestar atención. Google tiene una buena solución para esto. Google Inbox.

inbox

Abreviaturas usadas

Descripción

La perfecta integración de Google Inbox con el móvil ―al menos con Android― es perfecta. Permite gestionar varias cuentas de correo, obviamente todas Gmail, con una interfaz ligera con la que puedes cambiar de usuario con un solo gesto, tanto en el navegador del equipo como en el móvil.

Ejecución

Lo primero que tienes que hacer cuando entras en Inbox es entrar al menú,, a la izquierda de Recibidos.inbox1

Tras esto entras en configuración→otros.

inbox2

Y puedes redireccionar todo el tráfico de Gmail a Inbox marcándolo como indico. Si luego no te agrada o quieres dejar de probarlo, tan solo desactiva la redirección eliminando la marca.

Inbox, viene preparado para filtrar, filtrar mucho. Por defecto todos vienen creados unos contenedores para viajes, compras, finanzas, social, notificaciones, foros, promociones y la posibilidad de crear nuevos según tu conveniencia. No obstante yo los tengo desactivado, pues prefiero que me llegue todo al área de Recibidos. Verás por qué. El tratamiento correos de inbox es tan sumamente útil que de una vez por todas vas a tener la bandeja de entrada (Recibidos) vacía.

inbox3

Cuando pases el ratón por encima de cada email aparecen los manejadores que puedes ver a la derecha. El primero es para fijar el email a Recibidos mientras no elimines la chincheta. El segundo es para posponer. Una pasada. Puedes posponerlo para una hora, para otro día, incluso para otro lugar; yo lo he probado incluso con distintas provincias, funciona de maravilla. El tercero envía el email a la bandeja de completados, sin tener que leerlo si no te apetece. El cuarto es para clasificarlo si te apetece o moverlo a otro lugar.

Siempre podrás consultar los archivos pospuestos en su bandeja correspondiente. Igualmente con completados. Que lo elimines de la bandeja de Recibidos no significa que lo hayas eliminado. En absoluto. No obstante, esto también es configurable.

Verás que bajo la bandeja de Enviados, aparece un icono de Recordatorios.

inbox4

Otra maravilla. Olvídate de enviarte correos a ti mismo para acordarte de las cosas. Esto se integrará perfectamente con tu Google Calendar. Todos los recordatorios que tú actives estarán por defecto con la chincheta en la bandeja de recibidos y perfectamente clasificados en tu calendar, tanto en el ordenador como en tu móvil.

Tienes que saber que la «gestualidad» en el móvil es distinta a la del entorno en un navegador. En el móvil cuando recibes un correo lo mandas a completado desplazándolo a la derecha. Mientras que si lo desplazas a la izquierda estarás mandándolo a Pospuestos, listo para ser programado.

Mi táctica personal es como antes dije mantener la bandeja de entrada vacía. Nunca antes lo había conseguido con tanta comodidad.

Epílogo

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

exlibri, sapere aude
exlibri, sapere aude
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Comando ln para crear vínculos de archivos

Extracto

@pedroruizhidalg― Linux puede dar a un archivo más de un nombre usando la orden ln. Tal vez te interese hacer referencia a un archivo usando diferentes nombres para acceder a él desde diferentes directorios. A estos nombres adicionales se les conoce como vínculos.

Abreviaturas usadas

Descripción

La orden ln lleva dos argumentos: el nombre del archivo original y el nuevo nombre del archivo adicional. La operación ls listará ambos nombres de archivo, si bien, en realidad, físicamente ser trata de un solo archivo.

Existen dos tipos de vínculos, los vínculos simbólicos y los vínculos duros.

Ejecución

Vínculos duros:

Como forma general:

$ ln nombre-del-archivo-original nombre-añadido-del-archivo

Veamos un ejemplo práctico.

$ touch archivoOriginal
$ echo "este es el contenido del archvivo Original" > archivoOriginal 
$ cat archivoOriginal 
este es el contenido del archvivo Original
$ ln archivoOriginal otroarchivo
$ ls
archivoOriginal otroarchivo
$ cat otroarchivo 
este es el contenido del archvivo Original
$

Puede parecer que se trate de una copia, pero no lo es. Realmente estamos accediendo al mismo archivo con otro nombre. Si ahora estuviera dando clases pondría el ejemplo. Yo contesto a mi esposa cuando me llama “Pedro” y a mi hija cuando me llama “papá”, si bien yo sigo siendo el mismo. Pasemos a otra cosa:

En el ejemplo anterior he puesto en negrita lo que tenemos que teclear y he dejado en texto normal el resultado que nos ofrece el ordenador. Pasemos a explicar los pasos.

  1. Con touch archivoOriginal creamos un archivo vacío.
  2. Con la siguiente orden echo introducimos en el archivoOriginal la cadena de texto que está entre comillas.
  3. Con la orden cat comprobamos el contenido de archivoOriginal.
  4. El comando ln crea un vínculo a archivoOriginal.
  5. Mediante ls vemos que ahora disponemos de dos archivos diferentes.
  6. Con cat otroarchivo listamos su contenido y comprobamos que es idéntico al archivoOriginal.

¿Cómo estar seguros que se trata en realidad del mismo archivo?

Usando el comando ls con la opcion -li nos muestra el número de inodo que indica que en realidad apunta al mismo lugar físico.

$ ls -li
total 8
4980891 -rw-rw-r-- 2 pedro pedro 43 oct 26 19:59 archivoOriginal
4980891 -rw-rw-r-- 2 pedro pedro 43 oct 26 19:59 otroarchivo
$

Observamos en los números en negrita que se trata de idéntica localización de inodo.

Un vínculo duro puede fallar en linux si está colocado en otro directorio, esto es debido a la segmentación que puede sufrir ―de hecho sufre― el sistema de archivos.

Vínculos simbólicos

Un vínculo simbólico indica un acceso a un directorio o fichero que se encuentra en un lugar distinto dentro de la estructura de directorios. Una modificación realizada utilizando este enlace se reflejará en el original; pero, por el contrario, si se elimina el enlace, no se eliminará el auténtico. Veamos el ejemplo:

$ ln -s archivoOriginal otroarchivo
$ ls -l
total 4
-rw-rw-r-- 1 pedro pedro 43 oct 26 19:59 archivoOriginal
lrwxrwxrwx 1 pedro pedro 15 oct 26 20:47 otroarchivo -> archivoOriginal

Si otroarchivo fuera movido a otro directorio seguiría apuntando al mismo archivo de forma efectiva al archivo al que pertenece.

Comprobamos que ambos apuntan al mismo inodo.

$ ls -li
total 4
4980891 -rw-rw-r-- 1 pedro pedro 43 oct 26 19:59 archivoOriginal
4981228 lrwxrwxrwx 1 pedro pedro 15 oct 26 20:47 otroarchivo -> archivoOriginal

Una práctica interesante, sería colocar en nuestro directorio .bin, un enlace simbólico al comando whish con el nombre «donde».

La orden which busca el directorio donde se encuentra un comando determinado. Por ejemplo which php en mi sistema responde /usr/bin/php

Ejecutamos lo siguiente:

$ which which
/usr/bin/which
$ cd ~/.bin
$ ln -s /usr/bin/which donde
  1. Usamos la orden which para obtener la localización del comando which.
  2. Nos situamos en nuestro directorio de ejecuciones de scripts.
  3. Realizamos un enlace simbólico al comando which desde ~/.bin/donde

A partir de este momento siempre que tengamos bien configurado el directorio de ejecuciones de scripts, podemos acceder al comando which mediante donde.

 $ donde php
/usr/bin/php
Tux: orden ln
comando ln

Epílogo

Como truco, la práctica totalidad de los enlaces que se realizan son enlaces simbólicos.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública @pedroruizhidalg.pub.key

#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Linux, comando file

linux shell bash

Extracto

@pedroruizhidalg― En ocasiones necesitamos clarificar el contenido de un directorio. En Linux todo es archivo. Es decir, el sistema operativo no necesita ni requiere las extensiones de los archivos. En otras palabras, podemos dar la extensión .mp3 a un archivo de python, o bien .txt a un archivo de sonido. Las extensiones para Linux «son cosas de humanos».

El comando file sirve para clarificar a qué tipo, o cómo se ejecuta ―qué papel juega― un archivo dentro del sistema. Bien usado puede ser una herramienta interesante.

Abreviaturas usadas

mp3― Formato de compresión digital para la transmisión rápida de archivos de audio y vídeo a través de Internet.

txt―Un archivo de texto llano, texto simple, texto plano, texto sencillo o texto pelado es un archivo informático compuesto únicamente por texto sin formato, sólo caracteres, lo que lo hace también legible por humanos. …

Descripción

El comando file determina el tipo al que pertenece un archivo. Este comando acepta la opción -f para poder leer la entrada desde un archivo. Algunas veces tenemos tal pollo formado en un directorio que esto termina por poner algo de luz en él.

$ file archivos
archivos: ASCII text
$

Ejecución

Por regla general, uso este comando de la siguiente forma:

$ ls > archivos
$ file -f archivos >> archivos
$ cat archivos
archivos
lexico.l
sintactico.tab.c
sintactico.tab.h
sintactico.y
archivos:         ASCII text
lexico.l:         UTF-8 Unicode text
sintactico.tab.c: C source, ASCII text
sintactico.tab.h: C source, ASCII text
sintactico.y:     C source, UTF-8 Unicode text
$
  1. Introducimos el listado del directorio en un archivo (al que llamo «archivo»).
  2. Ejecutamos el comando file con -f para que pueda tomar como entrada el archivo que hemos generado. Haciendo que él escriba añadiendo al archivo el análisis de tipo de los ficheros del directorio.
  3. Mostramos por la salida estándar el contenido de «archivo» y comprobamos que la primera parte corresponde a la descripción de los componentes del directorio y la segunda a su análisis de tipo.

Epílogo

 

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

9cf76-ubuntu

Clave pública @pedroruizhidalg.pub.key

#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel