Pregunta

Todos sabemos cómo utilizar <ctrl>-R para revertir la búsqueda a través del historial, pero ¿sabías que puedes usar <ctrl>-S para buscar hacia adelante si configura stty stop ""?Además, ¿alguna vez has intentado ejecutar bind -p para ver todos los atajos de teclado en la lista?Hay más de 455 en Mac OS X de forma predeterminada.

¿Cuál es tu truco oscuro, atajo de teclado o configuración de tienda favorito con bash?

¿Fue útil?

Solución 7

Al ejecutar comandos, a veces querré ejecutar un comando con los argumentos anteriores.Para hacer eso, puedes usar este atajo:

$ mkdir /tmp/new
$ cd !!:*

Ocasionalmente, en lugar de usar buscar, crearé un bucle de una línea si necesito ejecutar varios comandos en una lista de archivos.

for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;

Configurar las opciones del historial de la línea de comandos en mi .bash_login (o .bashrc) es realmente útil.El siguiente es un conjunto de configuraciones que uso en mi Macbook Pro.

Configurar lo siguiente hace que bash borre los comandos duplicados en su historial:

export HISTCONTROL="erasedups:ignoreboth"

También elevo bastante el tamaño de mi historial.¿Por qué no?No parece ralentizar nada en los microprocesadores actuales.

export HISTFILESIZE=500000
export HISTSIZE=100000

Otra cosa que hago es ignorar algunos comandos de mi historial.No es necesario recordar el comando de salida.

export HISTIGNORE="&:[ ]*:exit"

Definitivamente quieres configurar histappend.De lo contrario, bash sobrescribe su historial cuando sale.

shopt -s histappend

Otra opción que uso es cmdhist.Esto le permite guardar comandos de varias líneas en el historial como un solo comando.

shopt -s cmdhist

Finalmente, en Mac OS X (si no estás usando el modo vi), querrás restablecer <CTRL>-S para que no se detenga el desplazamiento.Esto evita que bash pueda interpretarlo como una búsqueda directa.

stty stop ""

Otros consejos

Cambiar el nombre/mover archivos con sufijos rápidamente:
cp /home/foo/realllylongname.cpp{,-old}

Esto se expande a:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old

cd -

Es el equivalente en línea de comandos del botón Atrás (lo lleva al directorio anterior en el que se encontraba).

Otro favorito:

!!

Repite tu último comando.Más útil en el formulario:

sudo !!

Mi favorito es '^string^string2' que toma el último comando, reemplaza string con string2 y lo ejecuta

$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz

Guía del historial de la línea de comandos de Bash

rebautizar

Ejemplo:

$ ls
this_has_text_to_find_1.txt
this_has_text_to_find_2.txt
this_has_text_to_find_3.txt
this_has_text_to_find_4.txt

$ rename 's/text_to_find/been_renamed/' *.txt
$ ls
this_has_been_renamed_1.txt
this_has_been_renamed_2.txt
this_has_been_renamed_3.txt
this_has_been_renamed_4.txt

Tan útil

soy fanático de la !$, !^ y !* expandos, regresando, desde la línea de comando enviada más reciente:el último elemento, el primer elemento que no es de comando y todos los elementos que no son de comando.A saber (tenga en cuenta que el shell imprime el comando primero):

$ echo foo bar baz
foo bar baz
$ echo bang-dollar: !$ bang-hat: !^ bang-star: !*
echo bang-dollar: baz bang-hat: foo bang-star: foo bar baz
bang-dollar: baz bang-hat: foo bang-star: foo bar baz

Esto resulta útil cuando, por ejemplo, dices ls filea fileb, y quiero editar uno de ellos: vi !$ o ambos: vimdiff !*.También se puede generalizar a "la nº argumento" así:

$ echo foo bar baz
$ echo !:2
echo bar
bar

Finalmente, con los nombres de ruta, puede acceder a partes de la ruta agregando :h y :t a cualquiera de los expandos anteriores:

$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h  Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id

como listar solo subdirectorios en el actual?

ls -d */

Es un truco simple, ¡pero no sabrías cuánto tiempo necesité para encontrarlo!

ESC.

Inserta los últimos argumentos de su último comando bash.Resulta más útil de lo que crees.

cp file /to/some/long/path

cd ESC.

Seguro que puede "diff file1.txt file2.txt", pero Bash admite sustitución de procesos, que le permite diff la salida de comandos.

Por ejemplo, digamos que quiero asegurarme de que mi script me brinde el resultado que espero.Puedo simplemente envolver mi script en <( ) y enviarlo a diff para obtener una prueba unitaria rápida y sucia:

$ cat myscript.sh
#!/bin/sh
echo -e "one\nthree"
$
$ ./myscript.sh 
one
three
$
$ cat expected_output.txt
one
two
three
$
$ diff <(./myscript.sh) expected_output.txt
1a2
> two
$

Como otro ejemplo, digamos que quiero verificar si dos servidores tienen la misma lista de RPM instalados.En lugar de enviar mensajes a cada servidor, escribir cada lista de RPM en archivos separados y hacer un diff en esos archivos, puedo hacer lo mismo diff desde mi estación de trabajo:

$ diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')
241c240
< kernel-2.6.18-92.1.6.el5
---
> kernel-2.6.18-92.el5
317d315
< libsmi-0.4.5-2.el5
727,728d724
< wireshark-0.99.7-1.el5
< wireshark-gnome-0.99.7-1.el5
$

Hay más ejemplos en la guía avanzada de escritura de bash en http://tldp.org/LDP/abs/html/process-sub.html.

Mi comando favorito es "ls -thor"

Convoca a la poder de los dioses para enumerar los archivos modificados más recientemente en un formato convenientemente legible.

Es más novedoso, pero es inteligente...

Los 10 comandos principales utilizados:

$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head

Salida de muestra:

 242 git
  83 rake
  43 cd
  33 ss
  24 ls
  15 rsg
  11 cap
  10 dig
   9 ping
   3 vi

^R búsqueda inversa.Presione ^R, escriba un fragmento de un comando anterior que desee hacer coincidir y presione ^R hasta que encuentre el que desea.Entonces no tengo que recordar los comandos usados ​​recientemente que todavía están en mi historial.No exclusivamente bash, sino también:^E para final de línea, ^A para comienzo de línea, ^U y ^K para eliminar antes y después del cursor, respectivamente.

A menudo tengo alias para vi, ls, etc.pero a veces quieres escapar del alias.Simplemente agregue una barra invertida al comando al frente:

P.ej:

$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM

Genial, ¿no?

Aquí hay un par de ajustes de configuración:

~/.inputrc:

"\C-[[A": history-search-backward
"\C-[[B": history-search-forward

Esto funciona igual que ^R pero usando las teclas de flecha en su lugar.Esto significa que puedo escribir (por ejemplo) cd /media/ luego presione la flecha hacia arriba para ir a lo último que cdestaba dentro del /media/ carpeta.

(Yo uso Gnome Terminal, es posible que tengas que cambiar los códigos de escape de otros emuladores de terminal).

La finalización de Bash también es increíblemente útil, pero es una adición mucho más sutil.En ~/.bashrc:

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Esto permitirá completar pestañas por programa (p. ej.intentar completar la tabulación cuando la línea de comando comienza con evince solo mostrará los archivos que evince puede abrir y también completará con pestañas las opciones de la línea de comando).

Funciona muy bien con esto también en ~/.inputrc:

set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on

Utilizo mucho lo siguiente:

El :p modificador para imprimir un resultado histórico.P.ej.

!!:p

Imprimirá el último comando para que pueda verificar que sea correcto antes de ejecutarlo nuevamente.solo ingresa !! para ejecutarlo.

En un sentido similar:

!?foo?:p

Buscará en su historial el comando más reciente que contenga la cadena 'foo' y lo imprimirá.

Si no necesita imprimir,

!?foo

hace la búsqueda y la ejecuta de inmediato.

Tengo un arma secreta: shell-fu.

Hay miles de consejos inteligentes, trucos interesantes y recetas eficaces que la mayoría de las veces caben en una sola línea.

Uno que me encanta (pero hago un poco de trampa ya que uso el hecho de que Python está instalado ahora en la mayoría de los sistemas Unix):

alias webshare='python -m SimpleHTTPServer'

Ahora, cada vez que escriba "webshare", el directorio actual estará disponible a través del puerto 8000.Realmente agradable cuando quieres compartir archivos con amigos en una red local sin una llave USB o un directorio remoto.La transmisión de vídeo y música también funcionará.

Y, por supuesto, la clásica bomba de tenedor que es completamente inútil pero sigue siendo muy divertida:

$ :(){ :|:& };:

No intentes eso en un servidor de producción...

Puede utilizar el comando de vigilancia junto con otro comando para buscar cambios.Un ejemplo de esto fue cuando estaba probando mi enrutador y quería obtener números actualizados sobre cosas como la relación señal-ruido, etc.

watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG

Para encontrar todos los lugares donde el Prog está disponible, generalmente en algún lugar de ~/bin en lugar de el de/usr/bin/prog que podría haberse esperado.

Me gusta construir comandos con eco y canalizarlos al caparazón:

$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s

¿Por qué?Porque me permite ver lo que se va a hacer antes de hacerlo.De esa manera, si tengo un error horrible (como eliminar mi directorio de inicio), puedo detectarlo antes de que suceda.Obviamente, esto es más importante para acciones destructivas o irrevocables.

Cuando descargo un archivo grande, a menudo hago:

while ls -la <filename>; do sleep 5; done

Y luego simplemente ctrl+c cuando haya terminado (o si ls devuelve distinto de cero).Es similar al watch programa pero utiliza el shell en su lugar, por lo que funciona en plataformas sin watch.

Otra herramienta útil es netcat, o nc.Si lo haces:

nc -l -p 9100 > printjob.prn

Luego puede configurar una impresora en otra computadora, pero en su lugar use la dirección IP de la computadora que ejecuta netcat.Cuando se envía el trabajo de impresión, lo recibe la computadora que ejecuta netcat y lo descarga en printjob.prn.

pushd y popd casi siempre es útil

Una forma preferida de navegar cuando uso varios directorios en lugares muy separados en una jerarquía de árbol es usar acf_func.sh (enumerado a continuación).Una vez definido, puedes hacer

cd --

para ver una lista de directorios recientes, con un menú numérico

discos compactos -2

para ir al segundo directorio más reciente.

Muy fácil de usar, muy práctico.

Aquí está el código:

# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

Expande líneas complicadas antes de presionar la temida entrada

  • Alt.+Control+milínea de expansión de shell (puede que sea necesario utilizar Esc, Control+mi en tu teclado)
  • Control+_deshacer
  • Control+X, *globo-expandir-palabra

$ echo !$ !-2^ * Alt.+Control+mi
$ echo aword someotherword * Control+_
$ echo !$ !-2^ * Control+X, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h

&C.

Siempre he sido partidario de:

ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line

yo también uso shopt -s cdable_vars, luego puede crear variables bash en directorios comunes.Entonces, para el árbol de fuentes de mi empresa, creo un montón de variables como:

export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"

entonces puedo cambiar a ese directorio por cd Dcentmain.

pbcopy

Esto se copia en el portapapeles del sistema Mac.Puedes canalizarle comandos...intenta:

pwd | pbcopy

$ touch {1,2}.txt
$ ls [12].txt
1.txt  2.txt
$ rm !:1
rm [12].txt
$ history | tail -10
...
10007  touch {1,2}.txt
...
$ !10007
touch {1,2}.txt
$ for f in *.txt; do mv $f ${f/txt/doc}; done

Usar 'set -o vi' desde la línea de comando, o mejor, en .bashrc, lo coloca en modo de edición vi en la línea de comando.Comienzas en el modo 'insertar' para que puedas escribir y retroceder como de costumbre, pero si cometes un error 'grande' puedes presionar la tecla esc y luego usar 'b' y 'f' para moverte como lo haces en vi.cw para cambiar una palabra.Particularmente útil después de haber abierto un comando de historial que desea cambiar.

Al igual que muchos de los anteriores, mi favorito actual es la pulsación de tecla [alt].(Teclas Alt y "." juntas) ¡Esto es lo mismo que $!(Inserta el último argumento del comando anterior) excepto que es inmediato y para mí más fácil de escribir.(Simplemente no se puede usar en scripts)

p.ej:

mkdir -p /tmp/test/blah/oops/something
cd [alt].

Encadene varios comandos juntos usando el && dominio:

./run.sh && tail -f log.txt

o

kill -9 1111 && ./start.sh
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top