10 usos sorprenents i misteriosos del símbol (!) o de l'operador a les ordres de Linux


El símbol o operador ! a Linux es pot utilitzar com a operador de negació lògica, així com per obtenir ordres de l'historial amb retocs o per executar una ordre executada prèviament amb modificacions. Totes les ordres següents s'han comprovat explícitament a bash Shell. Tot i que no ho he comprovat, una gran part d'aquests no s'executarà en un altre shell. Aquí entrem en els usos sorprenents i misteriosos del símbol o operador ! a les ordres de Linux.

És possible que no tingueu coneixement del fet que podeu executar una ordre des de la vostra ordre d'historial (ordres executades ja/anteriorment). Per començar, primer trobeu el número d'ordre executant l'ordre historial.

$ history

Ara executeu una ordre de l'historial només pel número en què apareix, a la sortida de l'historial. Diguem que executeu una ordre que apareix al número 1551 a la sortida de l'ordre historial.

$ !1551

I executa l'ordre (ordre superior en el cas anterior), que es trobava al número 1551. Aquesta manera de recuperar l'ordre ja executada és molt útil, especialment en el cas d'aquelles ordres que són llargues. Només heu de cridar-lo mitjançant ![Número en què apareix a la sortida de l'ordre de l'historial].

Podeu executar aquelles ordres que heu executat anteriorment per la seva seqüència d'execució, sent l'última ordre d'execució es representarà com a -1, l'últim com a -2, el setè com a -7,...

Primer executeu l'ordre de l'historial per obtenir una llista de l'última ordre executada. És necessari executar l'ordre de l'historial, perquè pugueu estar segur que no hi ha cap ordre com rm command > file i altres només per assegurar-vos que no executeu cap ordre perillosa accidentalment. A continuació, marqueu Sisena última ordre, Vuit última ordre i Desè darrera ordre.

$ history
$ !-6
$ !-8
$ !-10

Necessito llistar el contingut del directori '/home/$USER/Binary/firefox' així que vaig disparar.

$ ls /home/$USER/Binary/firefox

Aleshores em vaig adonar que hauria d'haver disparat 'ls -l' per veure quin fitxer s'hi pot executar? Així que hauria d'escriure tota l'ordre de nou! No, no necessito. Només necessito portar l'últim argument a aquesta nova ordre com:

$ ls -l !$

Aquí !$ portarà els arguments passats a l'última ordre a aquesta nova ordre.

Suposem que he creat un fitxer de text 1.txt a l'escriptori.

$ touch /home/avi/Desktop/1.txt

i després copieu-lo a /home/avi/Downloads utilitzant el camí complet a banda i banda amb l'ordre cp.

$ cp /home/avi/Desktop/1.txt /home/avi/downloads

Ara hem passat dos arguments amb l'ordre cp. El primer és '/home/avi/Desktop/1.txt' i el segon és '/home/avi/Downloads', anem a gestionar-los de manera diferent, només cal que executeu echo [arguments] per imprimir els dos arguments de manera diferent.

$ echo “1st Argument is : !^”
$ echo “2nd Argument is : !cp:2”

Tingueu en compte que el primer argument es pot imprimir com a \!^” i la resta dels arguments es poden imprimir executant \![Name_of_Command]:[Number_of_argument]”.

A l'exemple anterior, la primera ordre era cp i es necessitava el segon argument per imprimir. Per tant, \!cp:2, si alguna ordre diu que xyz s'executa amb 5 arguments i necessiteu obtenir el quart argument, podeu utilitzar \!xyz:4, i fes-lo servir com vulguis. Es pot accedir a tots els arguments mitjançant \!*”.

Podem executar l'última ordre executada a partir de paraules clau. Ho podem entendre de la següent manera:

$ ls /home > /dev/null						[Command 1]
$ ls -l /home/avi/Desktop > /dev/null		                [Command 2]	
$ ls -la /home/avi/Downloads > /dev/null	                [Command 3]
$ ls -lA /usr/bin > /dev/null				        [Command 4]

Aquí hem utilitzat la mateixa ordre (ls) però amb diferents interruptors i per a carpetes diferents. A més, hem enviat a la sortida de cada comanda a '/dev/null', ja que no tractarem la sortida de l'ordre, també la consola roman neta.

Ara executeu l'ordre de darrera execució sobre la base de les paraules clau.

$ ! ls					[Command 1]
$ ! ls -l				[Command 2]	
$ ! ls -la				[Command 3]
$ ! ls -lA				[Command 4]

Comproveu la sortida i us sorprendrà que esteu executant ordres ja executades només amb paraules clau ls.

Podeu executar/alterar la vostra darrera ordre d'execució utilitzant (!!). Cridarà l'última ordre d'execució amb alter/tweak a l'ordre actual. Us mostrem l'escenari

L'últim dia vaig executar un script d'una línia per obtenir la meva IP privada, així que executo,

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/

Aleshores, de sobte, em vaig adonar que necessitava redirigir la sortida de l'script anterior a un fitxer ip.txt, així que què he de fer? He de tornar a escriure tota l'ordre i redirigir la sortida a un fitxer? Bé, una solució fàcil és utilitzar la tecla de navegació UP i afegir > ip.txt per redirigir la sortida a un fitxer com.

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txt

Gràcies a la tecla de navegació UP de Life Savior aquí. Ara considereu la condició següent, la propera vegada que executi un script d'una línia.

$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:

Tan bon punt he executat l'script, el indicador de bash va retornar un error amb el missatge \bash: ifconfig: command not found, no em va ser difícil endevinar que executo aquesta ordre com a usuari on es trobava. s'ha d'executar com a root.

Aleshores, quina és la solució? És difícil iniciar sessió a l'arrel i després escriure tota l'ordre de nou! A més (tecla de navegació UP) en l'últim exemple no va venir a rescatar aquí. Tan? Hem de cridar a \!!” sense cometes, que cridarà l'última ordre per a aquest usuari.

$ su -c “!!” root

Aquí su és canviar l'usuari que és root, -c és executar l'ordre específic com a usuari i la part més important !! es substituirà per l'ordre i l'última ordre d'execució serà substituït aquí. Sí! Heu de proporcionar la contrasenya d'arrel.

Faig ús de !! sobretot en els escenaris següents,

1. Quan executo l'ordre apt-get com a usuari normal, acostumo a rebre un error que diu que no teniu permís per executar-lo.

$ apt-get upgrade && apt-get dist-upgrade

Error d'opps... no us preocupeu, executeu l'ordre següent per aconseguir-ho.

$ su -c !!

De la mateixa manera que ho faig,

$ service apache2 start
or
$ /etc/init.d/apache2 start
or
$ systemctl start apache2

OOPS Usuari no autoritzat per dur a terme aquesta tasca, així que executo..

$ su -c 'service apache2 start'
or
$ su -c '/etc/init.d/apache2 start'
or
$ su -c 'systemctl start apache2'

El ! (NO lògic) es pot utilitzar per executar l'ordre a tots els fitxers/extensions, excepte la que hi ha darrere de !.

R. Elimina tots els fitxers d'un directori excepte el que té el nom 2.txt.

$ rm !(2.txt)

B. Elimina tots els tipus de fitxer de la carpeta excepte el que té l'extensió pdf.

$ $ rm !(*.pdf)

Aquí farem servir ! -d per validar si el directori existeix o no seguit de l'operador AND lògic (&&) per imprimir aquest directori no existeix i l'operador OR lògic (||) > per imprimir el directori està present.

La lògica és, quan la sortida de [ ! -d /home/avi/Tecmint ] és 0, executarà allò que està més enllà de lògic I, en cas contrari, anirà a OR lògic (||) i executarà allò que està més enllà de OR lògic.

$ [ ! -d /home/avi/Tecmint ] && printf '\nno such /home/avi/Tecmint directory exist\n' || printf '\n/home/avi/Tecmint directory exist\n'

Similar a la condició anterior, però aquí si el directori desitjat no existeix, sortirà de l'ordre.

$ [ ! -d /home/avi/Tecmint ] && exit

Una implementació general en llenguatge de scripting on si el directori desitjat no existeix, en crearà un.

[ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint

Això és tot per ara. Si coneixeu o us trobeu amb qualsevol altre ús de ! que val la pena saber-ho, potser us agradaria fer-nos arribar el vostre suggeriment als comentaris. Seguiu connectat!