J'écris un script shell qui devrait être un peu sécurisé, c'est-à-dire qui ne transmet pas de données sécurisées via les paramètres des commandes et n'utilise de préférence pas de fichiers temporaires. Comment puis-je passer une variable au stdin d'une commande? Ou, si ce n'est pas possible, comment utiliser correctement les fichiers temporaires pour une telle tâche?
105
$PATH
? Donc, celacat
peut être remplacé soit/bin/cat "$@" | tee /attacker/can/read/this/file
Réponses:
Quelque chose d'aussi simple que:
la source
echo "$blah"
c'est mieux.blah=-n
,blah=-e
... utilisez à laprintf
place. unix.stackexchange.com/questions/65803/…printf '%s\n' "$blah"
? Avec ce un changement ( en évitant les nombreux pièges dansecho
la spécification « , qui excellente réponse de Stéphane va dans en détail Pourquoiprintf
mieux queecho
? Sur Unix et Linux , ou que la section utilisation de l' application desecho
spécifications touches sur plus brièvement) , il est un parfait réponse raisonnable.Passer une valeur à
stdin
dans bash est aussi simple que:Assurez-vous toujours de mettre des guillemets autour des expressions variables!
la source
<<<
ne sont pas garantis d'être disponibles, ils ne sont pas dans la base POSIX, pour autant que je sache. Ils fonctionneront comme prévu, tant que vous ne les exécutez quebash
. Je le mentionne seulement, car ils OP ont dit «shell» pas spécifiquement «bash». Bien qu'il ait marqué la question avecbash
... c'est donc toujours une réponse acceptable.echo
méthode en raison de la création d'un tuyau. La commande herestring sera entièrement traitée parbash
, bien que dans cette situation (comme indiqué) vous feriez mieux de savoir qu'elle fonctionnera sur votre bash, sinon tout message d'erreur produit en raison de la non prise en charge de herestrings entraînerait également une fuite de ces informations.echo
est un fichier . Pas de tuyau là-bas, non? C'est Unix, mais ça ne peut pas être autant Unix .printf '%s\n' "$var"
produit les mêmes résultats queecho "$var"
mais ne cassera pas si, par exemplevar=-en
, et ne nécessite même pas de bash.Notez que les
echo "$var" | command
opérations ' signifient que l'entrée standard est limitée à la (aux) ligne (s) renvoyée (s). Si vous souhaitez également que le terminal soit connecté, vous devrez être plus sophistiqué:Cela signifie que la ou les première (s) ligne (s) seront le contenu de
$var
mais le reste viendra de lacat
lecture de son entrée standard. Si la commande ne fait rien de trop compliqué (essayez d'activer l'édition de la ligne de commande ou exécutez comme levim
fait), tout ira bien. Sinon, vous devez être vraiment sophistiqué - je pense queexpect
ou l'un de ses dérivés est susceptible d'être approprié.Les notations de la ligne de commande sont pratiquement identiques - mais le deuxième point-virgule est nécessaire avec les accolades alors qu'il ne l'est pas entre parenthèses.
la source
( echo "$LIST"; cat - ) | sed 1q
cela fonctionne pour moi mais je dois appuyer sur ctrl d lorsque j'exécute ce script?cat -
continue à lire sur le clavier jusqu'à EOF ou interrompre, vous devez donc lui dire EOF en tapant control-D.cat
du tout si vous ne voulez pas d'entrée de terminal, comme dans la première ligne. Ou vous pouvez utilisercat
pour lister un fichier. Ou ... Si vous voulez que la commande lise l'entrée du terminal, vous devez lui dire quand elle a atteint la fin de l'entrée. Ou vous pouvez utiliser( echo "$var"; sed /quit/q - ) | command
; cela continue jusqu'à ce que vous tapiez une ligne contenant «quitter». Vous pouvez être infiniment inventif avec la façon dont vous le gérez. Méfiez-vous de la vieille légende urbaine d'un programme qui a cessé de fonctionner lorsque les utilisateurs ont commencé à travailler avec l'Équateur. Ils tapaient le nom de la capitale, Quito, et le programme se fermait.echo "$LIST" | sed 1q | ...
? Tout dépend de ce que vous faites. La<<EOF
notation devrait exiger un EOF au début d'une ligne seule quelque part dans le fichier. Je ne l'utiliserais pas, je pense - mais je ne suis toujours pas sûr de ce que vous essayez d'accomplir. Un simpleecho "$LIST" | command
ouecho $LIST | command
suffira probablement en pratique (et il est important que vous connaissiez la signification de la différence entre les deux).J'ai aimé la réponse de Martin, mais elle a quelques problèmes en fonction du contenu de la variable. Ce
est mieux si votre variable contient "ou!
la source
foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"
fonctionne très bien pour moi. Que font exactement les trois"
? AFAIK, vous êtes juste en train de préfixer et d'ajouter une chaîne vide.Le
cat
n'est pas vraiment nécessaire, mais il aide à mieux structurer le code et vous permet d'utiliser plus de commandes entre parenthèses comme entrée de votre commande.la source
$passwd
Selon la réponse de Martin, il existe une fonctionnalité bash appelée Here Strings (qui est elle-même une variante de la fonctionnalité Here Documents plus largement prise en charge ).
http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings
Notez que Here Strings semble être uniquement bash, donc, pour une meilleure portabilité, vous feriez probablement mieux d'utiliser la fonction originale Here Documents, selon la réponse de PoltoS:
Ou, une variante plus simple de ce qui précède:
Vous pouvez omettre
(
et)
, sauf si vous souhaitez que cela soit redirigé vers d'autres commandes.la source
Cette méthode robuste et portable est déjà apparue dans les commentaires. Ce devrait être une réponse autonome.
ou
Remarques:
echo
, les raisons sont ici: pourquoi vautprintf
mieux queecho
?printf "$var"
est faux. Le premier argument est le format où diverses séquences aiment%s
ou\n
sont interprétées . Pour passer la variable à droite, elle ne doit pas être interprétée comme format.Les variables ne contiennent généralement pas de retours à la ligne finaux. L'ancienne commande (avec
%s
) transmet la variable telle quelle. Cependant, les outils qui fonctionnent avec du texte peuvent ignorer ou se plaindre d'une ligne incomplète (voir Pourquoi les fichiers texte devraient-ils se terminer par une nouvelle ligne? ). Vous pouvez donc souhaiter la dernière commande (avec%s\n
) qui ajoute un caractère de nouvelle ligne au contenu de la variable. Faits non évidents:<<<"$var" my_cmd
) ajoute une nouvelle ligne.my_cmd
, même si la variable est vide ou indéfinie.la source
Essaye ça:
la source
ps -u
quand echo est en cours d'exécution?echo
est un intégré, il n'y a donc aucun processus à afficher dans psecho "$variable"
c'est mieux.Faites simplement:
Si la variable ne contient pas d'espaces, les guillemets peuvent être omis.
Si vous utilisez bash, vous pouvez également faire:
Évitez d'utiliser echo sans -n car il redirigera la vraiable avec un saut de ligne ajouté à la fin.
la source
%s
, printf n'imprimera rien.my_var="%s"; printf "$my_var";
- peut-être essayerprintf "%s" "$my_var" | my_cmd
?