Je voudrais pouvoir utiliser le résultat de la dernière commande exécutée dans une commande ultérieure. Par exemple,
$ find . -name foo.txt
./home/user/some/directory/foo.txt
Maintenant, disons que je veux pouvoir ouvrir le fichier dans un éditeur, ou le supprimer, ou faire autre chose avec lui, par exemple
mv <some-variable-that-contains-the-result> /some/new/location
Comment puis-je le faire? Peut-être en utilisant une variable bash?
Mettre à jour:
Pour clarifier, je ne veux pas attribuer les choses manuellement. Ce que je cherche, c'est quelque chose comme des variables bash intégrées, par exemple
ls /tmp
cd $_
$_
contient le dernier argument de la commande précédente. Je veux quelque chose de similaire, mais avec la sortie de la dernière commande.
Dernière mise à jour:
La réponse de Seth a très bien fonctionné. Quelques points à garder à l'esprit:
- n'oubliez pas de le faire
touch /tmp/x
lorsque vous essayez la solution pour la toute première fois - le résultat ne sera stocké que si le code de sortie de la dernière commande a réussi
linux
bash
command-line
Armandino
la source
la source
Réponses:
C'est une solution vraiment pirate, mais elle semble fonctionner la plupart du temps une partie du temps. Pendant les tests, j'ai remarqué que cela ne fonctionnait parfois pas très bien lors de l'obtention d'un^C sur la ligne de commande, bien que je l'ai modifié un peu pour qu'il se comporte un peu mieux.
Ce hack est un hack en mode interactif uniquement, et je suis convaincu que je ne le recommanderais à personne. Les commandes en arrière-plan sont susceptibles de provoquer un comportement encore moins défini que la normale. Les autres réponses sont un meilleur moyen d'obtenir des résultats par programme.
Cela étant dit, voici la "solution":
Définissez cette variable d'environnement bash et émet les commandes souhaitées.
$LAST
aura généralement la sortie que vous recherchez:la source
PROMPT_COMMAND='last="$(cat /tmp/last)";lasterr="$(cat /tmp/lasterr)"; exec >/dev/tty; exec > >(tee /tmp/last); exec 2>/dev/tty; exec 2> >(tee /tmp/lasterr)'
qui fournit à la fois$last
et$lasterr
.No such file or directory
2> >(tee /tmp/lasterr 1>&2)
car la sortie standard detee
doit être redirigée vers l'erreur standard.Je ne connais aucune variable qui fasse cela automatiquement . Pour faire autre chose que de simplement copier-coller le résultat, vous pouvez relancer ce que vous venez de faire, par exemple
Où
!!
est l'expansion de l'historique signifiant «la commande précédente».Si vous vous attendez à ce qu'il y ait un seul nom de fichier avec des espaces ou d'autres caractères pouvant empêcher l'analyse correcte des arguments, citez le résultat (
vim "$(!!)"
). Le laisser sans guillemets permettra d'ouvrir plusieurs fichiers à la fois tant qu'ils n'incluent pas d'espaces ou d'autres jetons d'analyse du shell.la source
vim `!!`
date "+%N"
puisecho $(!!)
Bash est une sorte de langue laide. Oui, vous pouvez affecter la sortie à la variable
Mais mieux vaut espérer que votre plus durfind
n'a retourné qu'un seul résultat et que ce résultat ne contenait aucun caractère "impair", comme les retours chariot ou les sauts de ligne, car ils seront modifiés en silence lorsqu'ils seront affectés à une variable Bash.Mais mieux vaut faire attention à bien citer votre variable lors de son utilisation!
Il vaut mieux agir directement sur le fichier, par exemple avec
find
's-execdir
(consulter le manuel).ou
la source
echo "${MY_VAR}"
pour voir que c'est le cas.Il existe plusieurs façons de procéder. Une façon est d'utiliser
v=$(command)
qui affectera la sortie de la commande àv
. Par exemple:Et vous pouvez également utiliser des contre-citations.
À partir du guide du débutant Bash ,
EDIT: Après la modification de la question, il semble que ce n'est pas ce que l'OP recherche. Autant que je sache, il n'y a pas de variable spéciale comme
$_
pour la sortie de la dernière commande.la source
C'est assez simple. Utilisez des contre-citations:
Et puis vous pouvez l'utiliser à tout moment dans le futur
la source
Disclamers:
Lors de l'exécution d'un shell interactif dans tmux, vous pouvez facilement accéder aux données actuellement affichées sur un terminal. Jetons un coup d'œil à quelques commandes intéressantes:
Ouais, cela nous donne beaucoup de possibilités maintenant :) Quant à moi, j'ai mis en place un simple alias:
alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"
et maintenant chaque fois que j'ai besoin d'accéder à la dernière ligne, j'utilise simplement$(L)
pour l'obtenir.Ceci est indépendant du flux de sortie utilisé par le programme (que ce soit stdin ou stderr), de la méthode d'impression (ncurses, etc.) et du code de sortie du programme - les données doivent juste être affichées.
la source
Je pense que vous pourrez peut-être pirater une solution qui consiste à définir votre shell sur un script contenant:
Ensuite, si vous définissez
$PROMPT_COMMAND
pour afficher un délimiteur, vous pouvez écrire une fonction d'assistance (peut-être appelée_
) qui vous obtient le dernier morceau de ce journal, vous pouvez donc l'utiliser comme:la source
Vous pouvez configurer l'alias suivant dans votre profil bash:
Ensuite, en tapant «s» après une commande arbitraire, vous pouvez enregistrer le résultat dans une variable shell «it».
Ainsi, un exemple d'utilisation serait:
la source
grab
fonction qui copie la nième ligne de la dernière commande dans le presse-papiers gist.github.com/davidhq/f37ac87bc77f27c5027eJe viens de distiller cette
bash
fonction à partir des suggestions ici:Ensuite, vous faites simplement:
Mise à jour : un utilisateur anonyme a suggéré de remplacer
echo
parprintf '%s\n'
qui a l'avantage de ne pas traiter les options comme-e
dans le texte saisi. Donc, si vous attendez ou rencontrez de telles particularités, considérez cette suggestion. Une autre option consiste à utiliser à lacat <<<$grab
place.la source
cat <<<$grab
option?man bash
: "Here Strings: Une variante des documents here, le format est:<<<word
Le mot est développé et fourni à la commande sur son entrée standard." Ainsi, la valeur de$grab
est envoyéecat
sur stdin, et lacat
renvoie simplement à stdout.En disant "j'aimerais pouvoir utiliser le résultat de la dernière commande exécutée dans une commande suivante", je suppose - vous voulez dire le résultat de n'importe quelle commande, pas seulement find.
Si tel est le cas, xargs est ce que vous recherchez.
find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}
OU si vous souhaitez voir la sortie en premier:
find . -name foo.txt -print0
!! | xargs -0 -I{} mv {} /some/new/location/{}
Cette commande traite plusieurs fichiers et fonctionne comme un charme même si le chemin et / ou le nom de fichier contient des espaces.
Notez la partie mv {} / some / new / location / {} de la commande. Cette commande est construite et exécutée pour chaque ligne imprimée par la commande précédente. Ici, la ligne imprimée par la commande précédente est remplacée à la place de {} .
Extrait de la page de manuel de xargs:
Pour plus de détails, voir la page de manuel:
man xargs
la source
Capturez la sortie avec des backticks:
la source
Je fais généralement ce que les autres ici ont suggéré ... sans la tâche:
Vous pouvez devenir plus chic si vous aimez:
la source
Si tout ce que vous voulez est de réexécuter votre dernière commande et d'obtenir la sortie, une simple variable bash fonctionnerait:
Ainsi, vous pouvez exécuter votre commande sur la sortie avec:
Cela engendrera un nouveau processus et réexécutera votre commande, puis vous donnera la sortie. Cela ressemble à ce que vous aimeriez vraiment être un fichier d'historique bash pour la sortie des commandes. Cela signifie que vous devrez capturer la sortie que bash envoie à votre terminal. Vous pouvez écrire quelque chose pour regarder le / dev ou / proc nécessaire, mais c'est compliqué. Vous pouvez aussi simplement créer un "tube spécial" entre votre terme et bash avec une commande tee au milieu qui redirige vers votre fichier de sortie.
Mais ces deux solutions sont en quelque sorte des solutions piratées. Je pense que la meilleure chose serait Terminator qui est un terminal plus moderne avec journalisation de sortie. Vérifiez simplement votre fichier journal pour les résultats de la dernière commande. Une variable bash similaire à celle ci-dessus rendrait cela encore plus simple.
la source
Voici une façon de le faire après avoir exécuté votre commande et décidé que vous souhaitez stocker le résultat dans une variable:
Ou si vous savez à l'avance que vous voudrez le résultat dans une variable, vous pouvez utiliser des accents inversés:
la source
Comme alternative aux réponses existantes: à utiliser
while
si vos noms de fichiers peuvent contenir des espaces vides comme celui-ci:Comme je l'ai écrit, la différence n'est pertinente que si vous devez vous attendre à des blancs dans les noms de fichiers.
NB: le seul élément intégré ne concerne pas la sortie mais l'état de la dernière commande.
la source
vous pouvez utiliser !!: 1. Exemple:
la source
J'avais un besoin similaire, dans lequel je voulais utiliser la sortie de la dernière commande dans la suivante. Un peu comme un | (tuyau). par exemple
à quelque chose comme -
Solution: a créé ce tuyau personnalisé. Vraiment simple, en utilisant xargs -
Fondamentalement rien en créant une main courte pour xargs, cela fonctionne comme du charme, et est vraiment pratique. J'ajoute simplement l'alias dans le fichier .bash_profile.
la source
Cela peut être fait en utilisant la magie des descripteurs de fichiers et
lastpipe
option shell.Cela doit être fait avec un script - l'option "lastpipe" ne fonctionnera pas en mode interactif.
Voici le script avec lequel j'ai testé:
Ce que je fais ici, c'est:
définition de l'option shell
shopt -s lastpipe
. Cela ne fonctionnera pas sans cela car vous perdrez le descripteur de fichier.en s'assurant que mon stderr est également capturé avec
2>&1
acheminer la sortie dans une fonction afin que le descripteur de fichier stdin puisse être référencé.
définir la variable en obtenant le contenu du
/proc/self/fd/0
descripteur de fichier, qui est stdin.J'utilise ceci pour capturer des erreurs dans un script, donc s'il y a un problème avec une commande, je peux arrêter le traitement du script et quitter immédiatement.
De cette façon, je peux ajouter
2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg
derrière chaque commande que je souhaite vérifier.Vous pouvez maintenant profiter de votre sortie!
la source
Ce n'est pas strictement une solution bash mais vous pouvez utiliser le piping avec sed pour obtenir la dernière ligne de sortie des commandes précédentes.
Voyons d'abord ce que j'ai dans le dossier "a"
Ensuite, votre exemple avec ls et cd se transformerait en sed & piping en quelque chose comme ceci:
Ainsi, la magie réelle se produit avec sed, vous dirigez la sortie de la commande dans sed et sed imprime la dernière ligne que vous pouvez utiliser comme paramètre avec des graduations inverses. Ou vous pouvez également combiner cela à xargs. ("man xargs" dans shell est votre ami)
la source
Le shell n'a pas de symboles spéciaux de type Perl qui stockent le résultat d'écho de la dernière commande.
Apprenez à utiliser le symbole de tuyau avec awk.
Dans l'exemple ci-dessus, vous pouvez faire:
la source
est encore une autre façon, bien que sale.
la source
Je trouve que se souvenir de diriger la sortie de mes commandes dans un fichier spécifique est un peu ennuyeux, ma solution est une fonction dans mon
.bash_profile
qui capture la sortie dans un fichier et renvoie le résultat lorsque vous en avez besoin.L'avantage de celui-ci est que vous n'avez pas à réexécuter toute la commande (lors de l'utilisation
find
ou d'autres commandes de longue durée qui peuvent être critiques)Assez simple, collez ceci dans votre
.bash_profile
:Scénario
Usage
À ce stade, j'ai tendance à simplement ajouter
| catch
à la fin de toutes mes commandes, car cela ne coûte rien et cela m'évite d'avoir à réexécuter des commandes qui prennent beaucoup de temps à terminer.De plus, si vous souhaitez ouvrir la sortie du fichier dans un éditeur de texte, vous pouvez le faire:
la source