Vous voulez vérifier si une commande a réussi en redirigeant sa sortie vers une variable
J'écris actuellement un script bash qui charge les fichiers vidéo Jusqu'à YouTube en utilisant GoogleCL .
Comme je fais ce téléchargement dans une boucle (car il peut y avoir plusieurs fichiers vidéo), je voudrais vérifier si chaque fichier a été téléchargé avec succès avant de télécharger le suivant.
La commande google youtube post --access unlisted --category Tech $f
(où $F représente le fichier) affiche une chaîne qui me dit si le téléchargement a réussi ou non.
Mais je ne sais pas comment rediriger ça "return string" dans une variable pour vérifier les succès.
C'est ce que j'ai:
for f in ./*.ogv ./*.mov ./*.mp4
do
if [[ '*' != ${f:2:1} ]]
then
echo "Uploading video file $f"
# How to put the return value of the following command into a variable?
google youtube post --access unlisted --category Tech $f > /dev/null
# Now I assume that the output of the command above is available in the variable RETURNVALUE
if [[ $RETURNVALUE == *uploaded* ]]
then
echo "Upload successful."
else
echo "Upload failed."
fi
fi
done
Quelqu'un Peut-il m'aider?
7 réponses
Je suppose que vous pourriez également dépendre du code d'erreur de la commande google (je suppose qu'il renvoie une erreur s'il n'a pas réussi à télécharger, mais vous devriez probablement vérifier cela).
for f in ./*.ogv ./*.mov ./*.mp4; do
if [[ '*' != ${f:2:1} ]]; then
echo "Uploading video file $f"
if google youtube post --access unlisted --category Tech "$f" > /dev/null
then
echo "Upload successful."
else
echo "Upload failed."
fi
fi
done
Une idée fausse commune est que si veut évaluer une expression entre crochets, ce n'est pas vrai, si prend toujours une commande et vérifie l'état de l'erreur; généralement cette commande est [
qui est un alias pour test
, qui évalue l'expression. (Et oui, je serais surpris s'il n'y a pas un raccourci optimisé pour le faire aller plus vite dans bash, mais conceptuellement c'est toujours vrai).
La capture de la sortie se fait via des backticks, comme ceci
result=`command argument a b c`
Ou en utilisant $()
result=$(command argument a b c)
Mais il est probablement préférable d'utiliser le code d'erreur dans ce cas.
modifier:
Vous avez une drôle si chose dans votre fonction.. Je n'ai pas remarqué au début, mais cela peut être évité si vous activez l'option shell nullglob
(cela fera que ./*.mov
s'étendra à la chaîne vide, s'il n'y en a pas fichier). En outre, citez que $f
ou il se cassera si vos noms de fichiers contiennent des espaces
shopt -s nullglob
for f in ./*.ogv ./*.mov ./*.mp4; do
echo "Uploading video file $f"
if google youtube post --access unlisted --category Tech "$f" > /dev/null
then
echo "Upload successful."
else
echo "Upload failed."
fi
done
HTH.
Je l'appellerais, The command ... outputs a string
. ' Return ' est un mot-clé, et la valeur de retour est un nombre, où 0 signifie Par convention succès (0 erreurs) et une valeur différente indique un code d'erreur.
Vous saisissez la sortie par:
result=$(google youtube post --access unlisted --category Tech $f)
Mais verra souvent la solution inférieure:
result=`cmd param1 param2`
Inférieur, car les backticks sont facilement confondus avec les apostrophes (selon la police) et difficiles à imbriquer, alors ne les utilisez pas.
De 'Man bash':
La valeur de retour de une commande simple est son état de sortie, ou 128 + n Si le la commande est terminée par le signal n.
Et:
Retour [n]
Provoque la sortie d'une fonction avec la valeur de retour spécifiée par n. Si n est omis, le retour le statut est celui du dernier commande exécutée dans le corps de la fonction. Si utilisé en dehors d'un la fonction, mais lors de l'exécution d'un script par le . (source) de commande, le shell pour arrêter l'exécution de ce script et renvoie n ou l'état de sortie de la dernière commande exécuté dans le script comme état de sortie du script. Si utilisé en dehors d'une fonction et pas pendant l'exécution d'un script par . le retour d'état est faux. Toute commande associé au piège de retour est exécuté avant l'exécution reprend après la fonction ou le script.
La valeur de retour / code de sortie de la dernière commande est obtenue via$?.
Le mot clé pour la signification que vous vouliez dire est substitution de commande . Encore une fois 'Man bash':
Substitution De Commande
La substitution de commande permet à la sortie d'une commande de remplacer le nom de la commande. Il y a deux formes:$(command) or `command`
Bash effectue l'expansion en exécutant la commande et en remplaçant la substitution de commande par la norme sortie de la commande, avec tous les retours à la ligne de fin supprimés. Retours à la ligne intégrés ne sont pas supprimés, mais ils peuvent être supprimé pendant le fractionnement des mots. La commande substitution $(fichier cat) peut être remplacée par équivalent mais plus rapide $(
When the old-style backquote form of substitution is used,
La Barre oblique inverse conserve sa signification littérale sauf lorsqu'il est suivi par $, `, ou . Le premier backquote Non précédé d'une barre oblique inverse termine le substitution de commande. Lors de l'utilisation de la formulaire $(commande) , tous les caractères entre parenthèses composent la commande; aucun sont traités spécialement.
Command substitutions may be nested. To nest when using the
Backquoted forme, échapper à l'intérieur backquotes avec des barres obliques inverses.
Si la substitution apparaît entre guillemets, fractionnement de mots et l'expansion pathname ne sont pas effectuée sur les résultats.
Si vous obtenez toujours une sortie après > /dev/null
alors elle sort sur stderr, donc les backticks standard ou $()
ne fonctionneront pas.
Tout d'abord, voyez si le code de retour indique un problème: examinez $? après le succès et l'échec.
S'il s'avère que le code de retour n'est pas suffisant, vous pouvez rediriger la sortie:
RETURNVALUE=$(google youtube post --access unlisted --category Tech $f 2>&1 >/dev/null)
2>&1
met stderr sur le fd stdout, avant de rediriger stdout vers rien.
Utiliser $()
variable=$(google youtube post --access unlisted --category Tech $f )
, Vous pouvez l'affecter à une variable à l'aide de backticks:
CONTENT=`google youtube post --access unlisted --category Tech $f > /dev/null`
Exemple d'accès youtube
rm ~/temp/youtube_top_title1.txt rm ~/temp/youtube_top1.txt curl "http://www.youtube.com/"|\ grep -o 'watch[^"]*'|\ sort -n|\ uniq -c|\ awk '{if ($1!="1") print $2}'|\ while read i ; do\ page_youtube=`curl -s "http://www.youtube.com/${i}"`;\ echo `echo -e "$page_youtube" |awk '{if ($1 ~ "") start=1; if ($1 ~ "") start=0; if (start == 1) print $0 }'|grep -v ''` >> ~/temp/youtube_top_title1.txt url_current=$(echo -e "$page_youtube"|\ grep -o "url=[^,]*,"|\ sed 's/url=//g;s/,//g'|\ php -r '$f=fopen("php://stdin","r");while (FALSE!==($line=fgets($f))) echo urldecode($line);'|\ awk '{print $1}'|\ sed 's/;$//g'|\ sed 's/\\u.*//g'|\ tail -2|\ head -1) echo "$url_current" >> ~/temp/youtube_top1.txt done
La réponse à La question est d'utiliser le read
commande.
Bien sûr, toutes ces autres réponses montrent des façons de ne pas faire ce que l'OP a demandé, mais cela bousille vraiment le reste d'entre nous qui a cherché la question de L'OP.
Avertissement: Ceci est une réponse en double
Voici comment vous le faites...
Commande:
# I would usually do this on one line, but for readability...
series | of | commands \
| \
(
read string;
mystic_command --opt "$string" /path/to/file
) \
| \
handle_mystified_file
Voici ce qu'il fait et pourquoi il est important:
- supposons que le
series | of | commands
est une série très compliquée de commandes canalisées. -
mystic_command
est peut accepter stdin que le fichier, mais pas l'option arg donc doit venir comme une variable** -
read
prend stdin et le place dans la variable$string
- mettre le
read
et lemystic_command
dans un" sous-shell " via une parenthèse n'est pas nécessaire mais le fait couler comme un tuyau continu comme si les 2 commandes étaient dans un fichier de script séparé.
** Il y a toujours une alternative, et dans ce cas l'alternative est laide et illisible:
mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file