GNU/Linux >> Tutoriels Linux >  >> Linux

Comment affecter la sortie d'une commande à une variable Shell ?

Je souhaite affecter le résultat d'une expression
(c'est-à-dire la sortie d'une commande)
à une variable, puis la manipuler - par exemple,
la concaténer avec une chaîne, puis lui faire écho .
Voici ce que j'ai :

#!/bin/bash
cd ~/Desktop;
thefile= ls -t -U | grep -m 1 "Screen Shot";
echo "Most recent screenshot is: "$thefile;

Mais cela affiche :

Screen Shot 2011-07-03 at 1.55.43 PM.png
Most recent screenshot is: 

Donc, il semble que cela ne soit pas attribué à $thefile , et est imprimé au fur et à mesure de son exécution.

Qu'est-ce que je rate ?

Réponse acceptée :

Une affectation de shell est un mot unique, sans espace après le signe égal. Donc, ce que vous avez écrit attribue une valeur vide à thefile; de plus, puisque l'assignation est groupée avec une commande, elle rend thefile une variable d'environnement et l'affectation est locale à cette commande particulière, c'est-à-dire uniquement l'appel à ls voit la valeur attribuée.

Vous souhaitez capturer la sortie d'une commande, vous devez donc utiliser la substitution de commande :

thefile=$(ls -t -U | grep -m 1 "Screen Shot")

(Certaines publications montrent une syntaxe alternative thefile=`ls …` ; la syntaxe backquote est équivalente à la syntaxe dollar-parenthèses sauf que citer à l'intérieur des backquotes est parfois bizarre, alors utilisez simplement $(…) .)

Autres remarques sur votre script :

  • Combinaison -t (trier par heure) avec -U (ne pas trier avec GNU ls ) n'a pas de sens ; utilisez simplement -t .

  • Plutôt que d'utiliser grep pour faire correspondre les captures d'écran, il est plus clair de passer un caractère générique à ls et utilisez head pour capturer le premier fichier :

      thefile=$(ls -td -- *"Screen Shot"* | head -n 1)
    
  • C'est généralement une mauvaise idée d'analyser la sortie de ls . Cela pourrait échouer assez gravement si vous avez des noms de fichiers avec des caractères non imprimables. Cependant, trier les fichiers par date est difficile sans ls , c'est donc une solution acceptable si vous savez que vous n'aurez pas de caractères non imprimables ou de barres obliques inverses dans les noms de fichiers.

  • Utilisez toujours des guillemets autour des substitutions de variables , c'est-à-dire ici écrivez

      echo "Most recent screenshot is: $thefile"
    

    Sans guillemets doubles, la valeur de la variable est agrandie, ce qui causera des problèmes si elle contient des espaces ou d'autres caractères spéciaux.

  • Vous n'avez pas besoin de points-virgules à la fin d'une ligne. Ils sont redondants mais inoffensifs.

  • Dans un script shell, c'est souvent une bonne idée d'inclure set -e . Cela indique au shell de quitter si une commande échoue (en retournant un statut différent de zéro).

Si vous avez GNU find et sort (en particulier si vous utilisez Linux ou Cygwin non embarqué), il existe une autre approche pour trouver le fichier le plus récent :avoir find listez les fichiers et leurs dates, et utilisez sort et read (ici en supposant bash ou zsh pour -d '' pour lire un enregistrement délimité par NUL) pour extraire le fichier le plus récent.

IFS=/ read -rd ''ignoré lefichier <<( find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%[email protected]/%p
Linux
  1. Comment utiliser la commande basename ?

  2. Comment savoir si la sortie d'une commande ou d'un script shell est Stdout ou Stderr ?

  3. Comment ajouter la sortie à un fichier ?

  4. Comment stocker une commande dans une variable dans un script shell ?

  5. Comment conserver les sauts de ligne lors du stockage de la sortie de la commande dans une variable ?

Comment exécuter des commandes Shell via un serveur HTTP

Comment rediriger la sortie de la commande shell

Comment changer la couleur de sortie de 'Echo' sous Linux

Comment stocker une commande Linux en tant que variable dans un script shell

Comment exécuter une commande dans un script shell ?

Masquer la sortie d'une commande shell uniquement en cas de succès ?