Entrada

Mejores Prácticas de Desarrollo en Linux: Productividad y Automatización

Mejores Prácticas de Desarrollo en Linux: Productividad y Automatización

🎯 Configuración de Entorno de Desarrollo Profesional

Un entorno de desarrollo bien configurado puede aumentar tu productividad exponencialmente. En este post te mostraré cómo configurar un entorno Linux optimizado para desarrollo y automatización de tareas.


🚀 Terminal Poderoso con Zsh y Oh My Zsh

Instalación de Zsh

1
2
3
4
5
6
7
8
# Ubuntu/Debian
sudo apt install zsh

# Fedora/CentOS
sudo dnf install zsh

# Cambiar shell por defecto
chsh -s $(which zsh)

Oh My Zsh - Framework de configuración

1
2
3
4
5
6
7
# Instalar Oh My Zsh
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# Plugins recomendados para desarrollo
git clone https://github.com/zsh-users/zsh-autosuggestions.git $ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting
git clone https://github.com/agkozak/zsh-z $ZSH_CUSTOM/plugins/zsh-z

Configuración ~/.zshrc optimizada:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Tema potente
ZSH_THEME="powerlevel10k/powerlevel10k"

# Plugins esenciales
plugins=(
    git
    docker
    docker-compose
    kubectl
    python
    node
    npm
    zsh-autosuggestions
    zsh-syntax-highlighting
    zsh-z
    sudo
    history
    common-aliases
)

# Aliases útiles para desarrollo
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'

# Git aliases profesionales
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline --graph'
alias gco='git checkout'
alias gb='git branch'
alias gd='git diff'
alias gdc='git diff --cached'

# Docker aliases
alias dps='docker ps'
alias dpa='docker ps -a'
alias di='docker images'
alias dex='docker exec -it'
alias dlogs='docker logs -f'
alias dstop='docker stop $(docker ps -q)'
alias dprune='docker system prune -af'

# Kubernetes aliases
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kdesc='kubectl describe'
alias klogs='kubectl logs -f'

# Funciones útiles
mkcd() {
    mkdir -p "$1" && cd "$1"
}

extract() {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2)   tar xjf $1     ;;
            *.tar.gz)    tar xzf $1     ;;
            *.bz2)       bunzip2 $1     ;;
            *.rar)       unrar e $1     ;;
            *.gz)        gunzip $1      ;;
            *.tar)       tar xf $1      ;;
            *.tbz2)      tar xjf $1     ;;
            *.tgz)       tar xzf $1     ;;
            *.zip)       unzip $1       ;;
            *.Z)         uncompress $1  ;;
            *.7z)        7z x $1        ;;
            *)     echo "'$1' cannot be extracted via extract()" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}

# Búsqueda rápida de procesos
psgrep() {
    ps aux | grep -v grep | grep "$@" -i --color=auto;
}

# Información del sistema
sysinfo() {
    echo "=== INFORMACIÓN DEL SISTEMA ==="
    echo "Hostname: $(hostname)"
    echo "Uptime: $(uptime | awk '{print $3,$4}' | sed 's/,//')"
    echo "Kernel: $(uname -r)"
    echo "CPU: $(nproc) cores"
    echo "RAM: $(free -h | grep Mem | awk '{print $3 "/" $2}')"
    echo "Disk: $(df -h / | tail -1 | awk '{print $3 "/" $2 " (" $5 " used)"}')"
    echo "==============================="
}

📝 Editor Vim/Neovim Configurado

Instalación de Neovim

1
2
3
4
5
6
7
8
9
10
11
12
# Ubuntu/Debian
sudo apt install neovim

# Fedora
sudo dnf install neovim

# Arch
sudo pacman -S neovim

# Crear alias
echo "alias vim=nvim" >> ~/.zshrc
echo "alias vi=nvim" >> ~/.zshrc

Configuración ~/.config/nvim/init.vim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
" Configuración básica
set number
set relativenumber
set autoindent
set tabstop=4
set shiftwidth=4
set smarttab
set softtabstop=4
set mouse=a
set encoding=UTF-8
set termguicolors
set clipboard=unnamedplus

" Búsqueda mejorada
set ignorecase
set smartcase
set incsearch
set hlsearch

" Interfaz
set cursorline
set signcolumn=yes
set colorcolumn=80
set nowrap
set scrolloff=8
set sidescrolloff=8

" Plugins con vim-plug
call plug#begin()

Plug 'preservim/nerdtree'
Plug 'ryanoasis/vim-devicons'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'sheerun/vim-polyglot'
Plug 'dracula/vim', { 'as': 'dracula' }
Plug 'jiangmiao/auto-pairs'
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-surround'

call plug#end()

" Tema
colorscheme dracula

" Mapeos de teclas
let mapleader = " "

" NERDTree
nnoremap <leader>n :NERDTreeToggle<CR>
nnoremap <leader>f :NERDTreeFind<CR>

" FZF
nnoremap <leader>ff :Files<CR>
nnoremap <leader>fg :Rg<CR>
nnoremap <leader>fb :Buffers<CR>

" Navegación entre ventanas
nnoremap <leader>h <C-w>h
nnoremap <leader>j <C-w>j
nnoremap <leader>k <C-w>k
nnoremap <leader>l <C-w>l

" Git
nnoremap <leader>gs :Git<CR>
nnoremap <leader>gd :Gdiff<CR>
nnoremap <leader>gc :Git commit<CR>
nnoremap <leader>gp :Git push<CR>

" Autocomandos útiles
autocmd FileType python setlocal tabstop=4 shiftwidth=4 expandtab
autocmd FileType javascript setlocal tabstop=2 shiftwidth=2 expandtab
autocmd FileType html,css setlocal tabstop=2 shiftwidth=2 expandtab
autocmd FileType yaml setlocal tabstop=2 shiftwidth=2 expandtab
autocmd FileType go setlocal tabstop=4 shiftwidth=4 noexpandtab

📱 Tmux - Multiplexor de Terminal

Instalación y configuración básica

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# Instalar tmux
sudo apt install tmux  # Ubuntu/Debian
sudo dnf install tmux  # Fedora

# Configuración ~/.tmux.conf
cat > ~/.tmux.conf << 'EOF'
# Prefijo más cómodo
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# División de ventanas más intuitiva
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %

# Navegación entre paneles con Alt+arrows
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Redimensionar paneles
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# Habilitar mouse
set -g mouse on

# Numeración desde 1
set -g base-index 1
setw -g pane-base-index 1

# Renumeración automática
set -g renumber-windows on

# Colores
set -g default-terminal "screen-256color"

# Status bar
set -g status-bg colour235
set -g status-fg colour255
set -g status-left '#[fg=colour200,bold]#S '
set -g status-right '#[fg=colour200,bold]%Y-%m-%d %H:%M'
set -g window-status-current-format '#[fg=colour200,bold]#I:#W'

# Recargar configuración
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
EOF

# Recargar configuración
tmux source-file ~/.tmux.conf

Sesiones de trabajo predefinidas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# ~/scripts/dev-session.sh

SESSION_NAME="desarrollo"

# Crear sesión si no existe
tmux has-session -t $SESSION_NAME 2>/dev/null

if [ $? != 0 ]; then
    # Crear nueva sesión
    tmux new-session -d -s $SESSION_NAME

    # Ventana 1: Editor
    tmux rename-window -t $SESSION_NAME:1 'editor'
    tmux send-keys -t $SESSION_NAME:1 'cd ~/projects && nvim' C-m

    # Ventana 2: Terminal
    tmux new-window -t $SESSION_NAME:2 -n 'terminal'
    tmux send-keys -t $SESSION_NAME:2 'cd ~/projects' C-m

    # Ventana 3: Servidor/Docker
    tmux new-window -t $SESSION_NAME:3 -n 'servers'
    tmux send-keys -t $SESSION_NAME:3 'cd ~/projects' C-m

    # Ventana 4: Logs
    tmux new-window -t $SESSION_NAME:4 -n 'logs'
    
    # Volver a la primera ventana
    tmux select-window -t $SESSION_NAME:1
fi

# Conectar a la sesión
tmux attach-session -t $SESSION_NAME

🔧 Scripts de Automatización

Script de backup automático

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/bash
# ~/scripts/backup.sh

BACKUP_DIR="/home/$(whoami)/backups"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$BACKUP_DIR/backup_$DATE.log"

# Crear directorio de backup si no existe
mkdir -p "$BACKUP_DIR"

# Función de logging
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "=== INICIANDO BACKUP ==="

# Backup de dotfiles
log "Respaldando dotfiles..."
tar -czf "$BACKUP_DIR/dotfiles_$DATE.tar.gz" \
    ~/.zshrc \
    ~/.tmux.conf \
    ~/.config/nvim \
    ~/.gitconfig \
    ~/.ssh/config 2>/dev/null

# Backup de proyectos
if [ -d "$HOME/projects" ]; then
    log "Respaldando proyectos..."
    tar -czf "$BACKUP_DIR/projects_$DATE.tar.gz" \
        --exclude='node_modules' \
        --exclude='.git' \
        --exclude='__pycache__' \
        --exclude='*.pyc' \
        --exclude='.env' \
        "$HOME/projects"
fi

# Backup de base de datos (si existe)
if command -v mysqldump &> /dev/null; then
    log "Respaldando bases de datos MySQL..."
    mysqldump --all-databases > "$BACKUP_DIR/mysql_$DATE.sql" 2>/dev/null
fi

# Limpiar backups antiguos (mantener solo los últimos 7 días)
log "Limpiando backups antiguos..."
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.sql" -mtime +7 -delete

log "=== BACKUP COMPLETADO ==="

# Mostrar resumen
echo ""
echo "=== RESUMEN ==="
echo "Ubicación: $BACKUP_DIR"
echo "Archivos creados:"
ls -lh "$BACKUP_DIR"/*$DATE* 2>/dev/null
echo "Espacio utilizado: $(du -sh $BACKUP_DIR | cut -f1)"

Script de configuración de proyecto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#!/bin/bash
# ~/scripts/new-project.sh

PROJECT_NAME=$1
PROJECT_TYPE=${2:-"general"}

if [ -z "$PROJECT_NAME" ]; then
    echo "Uso: $0 <nombre_proyecto> [tipo]"
    echo "Tipos disponibles: python, node, go, docker, general"
    exit 1
fi

PROJECT_DIR="$HOME/projects/$PROJECT_NAME"

# Crear directorio del proyecto
mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"

# Inicializar git
git init
echo "# $PROJECT_NAME" > README.md

# Configuración específica por tipo
case $PROJECT_TYPE in
    "python")
        echo "=== Configurando proyecto Python ==="
        python3 -m venv venv
        source venv/bin/activate
        pip install --upgrade pip
        
        cat > requirements.txt << 'EOF'
# Dependencias de producción

# Dependencias de desarrollo
pytest
black
flake8
mypy
EOF
        
        cat > .gitignore << 'EOF'
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
venv/
env/
.env
.venv
ENV/
env.bak/
venv.bak/
EOF
        
        mkdir -p src tests docs
        touch src/__init__.py
        touch tests/__init__.py
        echo "print('Hello, $PROJECT_NAME!')" > src/main.py
        ;;
        
    "node")
        echo "=== Configurando proyecto Node.js ==="
        npm init -y
        
        cat > .gitignore << 'EOF'
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.npm
.eslintcache
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
dist/
build/
EOF
        
        mkdir -p src tests docs
        echo "console.log('Hello, $PROJECT_NAME!');" > src/index.js
        ;;
        
    "docker")
        echo "=== Configurando proyecto con Docker ==="
        
        cat > Dockerfile << 'EOF'
FROM alpine:latest

RUN apk add --no-cache \
    bash \
    curl \
    git

WORKDIR /app

COPY . .

CMD ["echo", "Hello from Docker!"]
EOF
        
        cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  app:
    build: .
    volumes:
      - .:/app
    environment:
      - NODE_ENV=development
EOF
        
        cat > .dockerignore << 'EOF'
.git
.gitignore
README.md
Dockerfile
.dockerignore
node_modules
npm-debug.log
EOF
        ;;
        
    "go")
        echo "=== Configurando proyecto Go ==="
        go mod init "$PROJECT_NAME"
        
        cat > main.go << 'EOF'
package main

import "fmt"

func main() {
    fmt.Printf("Hello, %s!\n", "World")
}
EOF
        
        cat > .gitignore << 'EOF'
# Binaries
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary
*.test

# Output of the go coverage tool
*.out

# Go workspace file
go.work
EOF
        ;;
esac

# Crear estructura común
mkdir -p docs scripts

cat > docs/DEVELOPMENT.md << EOF
# $PROJECT_NAME - Guía de Desarrollo

## Instalación

\`\`\`bash
git clone <repository-url>
cd $PROJECT_NAME
# Instrucciones específicas del proyecto
\`\`\`

## Desarrollo

\`\`\`bash
# Comandos para desarrollo local
\`\`\`

## Testing

\`\`\`bash
# Comandos para ejecutar tests
\`\`\`

## Deployment

\`\`\`bash
# Comandos para deployment
\`\`\`
EOF

# Script de desarrollo
cat > scripts/dev.sh << 'EOF'
#!/bin/bash
# Script de desarrollo local

echo "🚀 Iniciando entorno de desarrollo..."

# Agregar comandos específicos del proyecto aquí

echo "✅ Entorno listo!"
EOF

chmod +x scripts/dev.sh

# Commit inicial
git add .
git commit -m "Initial project setup"

echo ""
echo "✅ Proyecto '$PROJECT_NAME' creado exitosamente!"
echo "📁 Ubicación: $PROJECT_DIR"
echo "🎯 Tipo: $PROJECT_TYPE"
echo ""
echo "Próximos pasos:"
echo "1. cd $PROJECT_DIR"
echo "2. Configurar repositorio remoto: git remote add origin <url>"
echo "3. Comenzar desarrollo: ./scripts/dev.sh"

🔄 Gestión de Dotfiles con Git

Método del repositorio bare

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Configurar repositorio de dotfiles
git init --bare $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dotfiles config --local status.showUntrackedFiles no

# Agregar alias permanente
echo "alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> ~/.zshrc

# Uso
dotfiles add ~/.zshrc
dotfiles add ~/.tmux.conf
dotfiles add ~/.config/nvim/init.vim
dotfiles commit -m "Add initial dotfiles"
dotfiles remote add origin git@github.com:tuusuario/dotfiles.git
dotfiles push -u origin main

# Restaurar en nueva máquina
git clone --bare git@github.com:tuusuario/dotfiles.git $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dotfiles checkout
dotfiles config --local status.showUntrackedFiles no

🚀 Automatización con Cron y Systemd

Backup automático con cron

1
2
3
4
5
6
7
8
9
10
11
12
# Editar crontab
crontab -e

# Agregar líneas:
# Backup diario a las 2 AM
0 2 * * * /home/usuario/scripts/backup.sh

# Limpiar logs semanalmente
0 3 * * 0 find /var/log -name "*.log" -mtime +30 -delete

# Actualizar sistema los domingos a las 4 AM
0 4 * * 0 sudo apt update && sudo apt upgrade -y

Servicio systemd personalizado

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Crear servicio de monitoreo
sudo tee /etc/systemd/system/project-monitor.service << 'EOF'
[Unit]
Description=Monitor de Proyectos
After=network.target

[Service]
Type=simple
User=usuario
ExecStart=/home/usuario/scripts/monitor.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Habilitar y iniciar
sudo systemctl daemon-reload
sudo systemctl enable project-monitor.service
sudo systemctl start project-monitor.service

# Ver estado
sudo systemctl status project-monitor.service

📊 Monitoreo y Logging

Script de monitoreo del sistema

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
# ~/scripts/system-monitor.sh

LOG_FILE="/var/log/system-monitor.log"
THRESHOLD_CPU=80
THRESHOLD_MEM=90
THRESHOLD_DISK=85

# Función de alerta
send_alert() {
    local message="$1"
    echo "[ALERT] $(date): $message" | tee -a "$LOG_FILE"
    # Enviar notificación (opcional)
    # notify-send "System Alert" "$message"
    # echo "$message" | mail -s "System Alert" admin@example.com
}

# Monitorear CPU
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
cpu_usage_int=${cpu_usage%.*}

if [ "$cpu_usage_int" -gt "$THRESHOLD_CPU" ]; then
    send_alert "High CPU usage: ${cpu_usage}%"
fi

# Monitorear memoria
mem_usage=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100.0)}')

if [ "$mem_usage" -gt "$THRESHOLD_MEM" ]; then
    send_alert "High memory usage: ${mem_usage}%"
fi

# Monitorear disco
disk_usage=$(df / | tail -1 | awk '{print $5}' | cut -d'%' -f1)

if [ "$disk_usage" -gt "$THRESHOLD_DISK" ]; then
    send_alert "High disk usage: ${disk_usage}%"
fi

# Log de estado normal
echo "[INFO] $(date): CPU: ${cpu_usage}%, MEM: ${mem_usage}%, DISK: ${disk_usage}%" >> "$LOG_FILE"

🎯 Conclusión

Con estas configuraciones y scripts tendrás un entorno de desarrollo Linux altamente productivo:

  • Terminal poderoso con autocompletado y sugerencias
  • Editor eficiente con plugins para desarrollo
  • Multiplexor para gestionar múltiples sesiones
  • Automatización de tareas repetitivas
  • Backup automático de tu trabajo
  • Monitoreo del sistema

Próximos pasos:

  1. Personaliza las configuraciones según tus necesidades
  2. Crea más scripts de automatización
  3. Explora herramientas avanzadas como Ansible
  4. Implementa CI/CD para tus proyectos
  5. Aprende Docker y Kubernetes para containerización

💡 Recuerda: La productividad viene de la práctica constante y la automatización inteligente de tareas repetitivas.


Andrés Nuñez - t4ifi

Esta entrada está licenciada bajo CC BY 4.0 por el autor.