@ jw013 Bon point et excellents articles. J'aime la citation "Les variables contiennent des données, les fonctions contiennent du code." à partir du premier lien, mais pour mon usage, les données qui sont données à une fonction (dans ce cas, at) sont du code. Des conseils sur une manière plus sûre d'organiser / collecter le code qui sera donné à at?
Cory Klein
atprend la shsyntaxe en entrée. Générer des entrées pour atgénérer des shsyntaxes valides et correctement citées à partir d'entrées arbitraires, ce qui n'est pas anodin, j'essaierais donc de l'éviter si possible. Il serait vraiment utile que vous puissiez donner un peu plus de détails sur ce que vous essayez d'accomplir.
jw013
Désolé, je ne voulais pas vous distraire avec trop de détails, mais ce que je fais n'est pas vraiment compliqué, OMI. Je crée un script qui prend un "temps" et un "message". Il s'exécute ensuite atpendant le «temps» donné et indique atd'exécuter la commande dzen2. dzen2prend le "message" de stdin et utilise également d'autres paramètres statiques. La difficulté est que j'ai besoin de dzen2diriger le paramètre "message" de l'utilisateur dans la commande, mais je ne m'exécute pas dzen2moi-même, je dis atde le faire.
Il est également important de noter que les devis sont évalués différemment; les guillemets doubles (") permettent d'évaluer la chaîne incluse, les guillemets simples (') affichent la chaîne sous forme littérale. Exemple: "$(ls)"et '$(ls)'. C'est la raison pour laquelle les guillemets apparaissent dans les exemples de questions originales.
Joseph Kern
Un tableau est également une source de problèmes. Le code appartient aux fonctions, les données aux variables. L'exemple que vous présentez ne fonctionne que parce que les guillemets sont supprimés dans la division du tableau. Un printf '<%s> ' "${VAR[@]}"indique que les devis ont déjà été supprimés. Si vous définissez VAR comme VAR=(echo \"hi\")ayant réellement des guillemets, le même problème réapparaît, $ ${VAR[@]}sera imprimé"hi"
9
La suppression des devis ne se produit que sur les mots d'entrée d'origine, pas sur le résultat des extensions. Les citations qui font partie de variables étendues ne sont pas modifiées.
Si vous reculez un peu, vous pouvez voir pourquoi la substitution de variables doit absolument conserver les guillemets.
Le point de guillemets dans un shell Unix / Linux / BSD est de garder ensemble des morceaux d'une chaîne qui autrement seraient analysés en plusieurs chaînes. Étant donné que par défaut, un shell utilise des espaces comme séparateur de jetons, une chaîne avec des espaces (comme "un deux trois"), si elle n'est pas citée ou échappée d'une manière ou d'une autre, serait analysée en 3 chaînes: "un", "deux" et "trois".
Si un programmeur veut une chaîne avec la valeur d'une variable interpolée:
VAR=two
STRING="one $VAR three"
le shell ne doit absolument pas supprimer les guillemets: la chaîne contenant des espaces serait analysée comme 3 chaînes plus petites.
eval
est un champ de mines de failles de sécurité potentielles que vous devezat
) sont du code. Des conseils sur une manière plus sûre d'organiser / collecter le code qui sera donné àat
?at
prend lash
syntaxe en entrée. Générer des entrées pourat
générer dessh
syntaxes valides et correctement citées à partir d'entrées arbitraires, ce qui n'est pas anodin, j'essaierais donc de l'éviter si possible. Il serait vraiment utile que vous puissiez donner un peu plus de détails sur ce que vous essayez d'accomplir.at
pendant le «temps» donné et indiqueat
d'exécuter la commandedzen2
.dzen2
prend le "message" de stdin et utilise également d'autres paramètres statiques. La difficulté est que j'ai besoin dedzen2
diriger le paramètre "message" de l'utilisateur dans la commande, mais je ne m'exécute pasdzen2
moi-même, je disat
de le faire.Réponses:
La paire de devis supplémentaire ne serait consommée que par une étape d'évaluation supplémentaire. Par exemple forcé par
eval
:Mais c'est généralement une mauvaise idée de mettre des commandes avec des paramètres dans une chaîne. Utilisez plutôt un tableau:
la source
"$(ls)"
et'$(ls)'
. C'est la raison pour laquelle les guillemets apparaissent dans les exemples de questions originales.printf '<%s> ' "${VAR[@]}"
indique que les devis ont déjà été supprimés. Si vous définissez VAR commeVAR=(echo \"hi\")
ayant réellement des guillemets, le même problème réapparaît,$ ${VAR[@]}
sera imprimé"hi"
La suppression des devis ne se produit que sur les mots d'entrée d'origine, pas sur le résultat des extensions. Les citations qui font partie de variables étendues ne sont pas modifiées.
la source
Si vous reculez un peu, vous pouvez voir pourquoi la substitution de variables doit absolument conserver les guillemets.
Le point de guillemets dans un shell Unix / Linux / BSD est de garder ensemble des morceaux d'une chaîne qui autrement seraient analysés en plusieurs chaînes. Étant donné que par défaut, un shell utilise des espaces comme séparateur de jetons, une chaîne avec des espaces (comme "un deux trois"), si elle n'est pas citée ou échappée d'une manière ou d'une autre, serait analysée en 3 chaînes: "un", "deux" et "trois".
Si un programmeur veut une chaîne avec la valeur d'une variable interpolée:
le shell ne doit absolument pas supprimer les guillemets: la chaîne contenant des espaces serait analysée comme 3 chaînes plus petites.
la source