web-dev-qa-db-fra.com

Bash curl et variable au milieu de l'url

J'aurais besoin de lire certaines données en utilisant curl. Je lis essentiellement les mots-clés du fichier

while read line
do
    curl 'https://gdata.youtube.com/feeds/api/users/'"${line}"'/subscriptions?v=2&alt=json' \
         > '/home/user/archive/'"$line"
done < textfile.txt

Quoi qu'il en soit, je n'ai pas trouvé le moyen de créer l'URL à boucler pour que cela fonctionne. J'ai essayé comme toutes les versions possibles simples et doubles citées. J'ai essayé essentiellement:

'...'"$line"'...'
"..."${line}"..."
'...'$line'...'

et ainsi de suite. Nommez-le et je suis sûr que je l'ai essayé. 

Lorsque j'imprime l'URL dans le meilleur des cas, elle se présente comme suit:

 /subscriptions?v=2&alt=jsoneeds/api/users/KEYWORD FROM FILE

ou quelque chose de similaire. Si vous savez quelle pourrait en être la cause, j'apprécierais les informations. Merci!

10
Mare

Ce n'est pas une citation. Le problème est que votre fichier de mots-clés est au format DOS: chaque ligne se termine par un retour chariot et un saut de ligne (\ r\n) plutôt que par un saut de ligne (\ n). Le retour chariot est lu dans la variable de ligne et inclus dans l'URL. Le cadeau est que lorsque vous y faites écho, il semble imprimer:

/subscriptions?v=2&alt=jsoneeds/api/users/KEYWORD FROM FILE"

mais c'est vraiment l'impression:

https://gdata.youtube.com/feeds/api/users/KEYWORD FROM FILE
/subscriptions?v=2&alt=json

... avec juste un retour de voiture entre eux, alors le second écrase le premier.

Alors que pouvez-vous faire à ce sujet? Voici un moyen assez facile de couper le cr à la fin de la ligne:

cr=$'\r'
while read line
do
    line="${line%$cr}"
    curl "https://gdata.youtube.com/feeds/api/users/${line}/subscriptions?v=2&alt=json" \
         > "/home/user/archive/$line"
done < textfile.txt
16
Gordon Davisson

Votre version actuelle devrait fonctionner, je pense. Plus élégant consiste à utiliser une simple paire de guillemets doubles autour de l’URL entière avec la variable dans ${}:

"https://gdata.youtube.com/feeds/api/users/${line}/subscriptions?v=2&alt=json"
15
Fred Foo

Utilisez-le simplement comme ceci, cela devrait suffire:

curl "https://gdata.youtube.com/feeds/api/users/${line}/subscriptions?v=2&alt=json" > "/home/user/archive/${line}"

Si votre shell vous donne des problèmes avec &, mettez simplement \&, mais cela fonctionne bien pour moi sans cela.

5
Mattias Ahnberg

Si les données du fichier peuvent contenir des espaces et que vous ne vous opposez pas aux espaces du nom de fichier situé dans le répertoire /home/user/archive, vos résultats doivent alors être corrects.

Étant donné le contenu du reste de l'URL, vous pouvez même écrire:

while read line
do
    curl "https://gdata.youtube.com/feeds/api/users/${line}/subscriptions?v=2&alt=json" \
         > "/home/user/archive/${line}"
done < textfile.txt

où strictement le ${line} pourrait être juste $line aux deux endroits. Cela fonctionne car les chaînes sont corrigées et ne contiennent pas de métacaractères Shell.

Puisque votre code est proche de cela, mais que vous affirmez que vous voyez les mots-clés du fichier au mauvais endroit, il est peut-être préférable de réécrire un peu pour faciliter le débogage:

while read line
do
    url="https://gdata.youtube.com/feeds/api/users/${line}/subscriptions?v=2&alt=json"
    file="/home/user/archive/${line}"
    curl "$url" > "$file"
done < textfile.txt

Puisque les chaînes peuvent finir par contenir des espaces, semble-t-il (avez-vous besoin de développer les espaces à + dans l'URL?), Les guillemets autour des variables sont fortement recommandés. Vous pouvez maintenant exécuter le script avec sh -x (ou ajouter une ligne set -x au script) et voir ce que le shell pense faire comme il le fait.

1
Jonathan Leffler