web-dev-qa-db-fra.com

Écrire la sortie dynamique du terminal dans un fichier texte

Cela revient à pouvoir enregistrer le dynamic output (je vais expliquer) du terminal dans un fichier texte, mais voici ce que je cherche en fin de compte.

J'ai créé une commande personnalisée pour le terminal appelée playRandom. Elle lit les chansons au hasard pour toujours. Le fichier bash que j'ai créé pour cela:

#!/bin/bash 
find ./ -type f | sort -R | xargs -I + play +

Remarque: La commande play provient du logiciel SoX .

Maintenant, la sortie ressemble à ceci:

playRandom command

Comme vous pouvez voir les changements de sortie dynamically, je ne peux donc pas utiliser >> pour enregistrer la sortie.

Je veux pouvoir sauvegarder les noms des chansons jouées dans un fichier texte.

Comment puis-je atteindre cet objectif? Merci d'avance.

4
deergadan

Enregistrer les noms de fichiers en cours de lecture

Puisque la commande play se termine après la lecture d’un seul fichier, nous pouvons au lieu d’utiliser xargs et donner à play un lot de fichiers. Nous allons extraire chaque fichier, un à la une heure, et l'écho pour déposer, et lire le fichier par la suite. Le script édité ressemblerait à celui ci-dessous. Notez que des options supplémentaires et la commande IFS= read -d'' -r sont ajoutées pour gérer les noms de fichiers de manière sécurisée.

#!/bin/bash 

# create file for playing songs first
echo > playlist.txt

# Now play each song and echo filename to file
find ./ -type f -print0 | sort -z -R | while IFS= read -d '' -r filename
do
    clear
    echo "$filename" >> playlist.txt
    play "$filename"
done

L'avantage de cette approche est que les noms de fichiers vont dans playlist.txt au fur et à mesure qu'ils sont lus, ce qui nous permet de suivre la sortie du script en temps réel avec quelque chose comme tail -F playlist.txt.

NOTE: pour éviter que playlist.txt ne soit répertorié dans la commande de find de modification de la sortie find comme suit:

find ./ -type f -not -name "playlist.txt" -print0

De plus, si nous voulons nous assurer que seuls les fichiers .mp3 sont répertoriés, nous pouvons le faire:

find ./ -type f \( -not -name "playlist.txt" -and -name "*.mp3" \) -print0

Sauvegarde de la liste des fichiers trouvés à lire

Si notre objectif est de sécuriser la liste de fichiers avant qu'elle ne soit lue , il n'y a pas beaucoup de données scientifiques, le pipeline de recherche-tri peut être écrit fichier en premier, et ce fichier peut ensuite être envoyé à play soit via xargs, soit à nouveau via la structure while IFS= read -r ; do ... done

#!/bin/bash 

find ./ -type f -print0 | sort -z -R > playlist.txt

while IFS= read -d '' -r filename
do
    clear
    play "$filename"
done < playlist.txt
10
find ./ -type f | sort -R | tee text.file | xargs -I + play +  

Voir aussi man tee.

8
waltinator

Voici ma solution:

1. Temps réel (en cours de lecture)

Après avoir exécuté la commande play, utilisez ceci:

soxi "$(readlink /proc/`pidof play`/fd/3)" | grep -Po "(?<=Title=).*"

Le nom de la chanson en cours de lecture vous sera renvoyé et vous pourrez le rediriger vers un fichier à l'aide de >.

1.1. Remarques

/proc/`pidof play`/fd/3
  • est le descripteur de fichier de votre piste en cours de lecture (fichier).
  • en utilisant readlink on obtient le nom du fichier
  • en utilisant soxi on obtient ses informations
  • en utilisant grep nous coupons le titre de la piste

2. Avant de jouer (Lister tous les noms)

find ./ -type f | sort -R | tee /tmp/play-files | xargs -I + soxi "+"\
| grep -Po "(?<=Title=).*" > list_of_names && xargs < /tmp/play-files\
-I + play "+"

Il créera un fichier nommé list_of_names dans votre répertoire actuel, qui contient tous les noms de piste.

3
Ravexina