Découpage /proc/cmdline arguments avec des espaces
La plupart des scripts qui parse /proc/cmdline décomposer en mots, puis filtrer arguments avec une instruction du cas, exemple:
CMDLINE="quiet union=aufs wlan=FOO"
for x in $CMDLINE
do
»···case $x in
»···»···wlan=*)
»···»···echo "${x//wlan=}"
»···»···;;
»···esac
done
Le problème, c'est quand le WLAN ESSID a espaces. Les utilisateurs s'attendent à définir wlan='FOO
BAR " (comme une variable du shell) et ensuite obtenir le résultat inattendu de 'FOO
avec le code ci-dessus, depuis la boucle de fentes sur les espaces.
Est-il un meilleur moyen de l'analyse de la /proc/cmdline
à partir d'un script shell de tomber à court de près de evaling?
Ou est-il en citant des astuces? Je pensais que je pouvais peut-être demander aux utilisateurs de l'entité en citer des espaces et de décoder comme suit: /bin/busybox httpd -d "FOO%20BAR"
. Ou est-ce une mauvaise solution?
Ok, j'ai fait la même erreur que JesperE...
OriginalL'auteur hendry | 2009-06-14
Vous devez vous connecter pour publier un commentaire.
Il y a quelques façons:
cat /proc/PID/cmdline | tr '\000' ' '
cat /proc/PID/cmdline | xargs -0 echo
Ces fonctionnera avec la plupart des cas, mais échoue lorsque les arguments sont séparés par des espaces. Cependant, je ne pense qu'il y aurait à améliorer les approches de l'aide
/proc/PID/cmdline
./proc/cmdline
est tout à fait différent de/proc/PID/cmdline
...Pour être plus précis
/proc/cmdline
est la ligne de commande fournie au noyau par certains bootloader (GrUB, LiLo, SysLinux, etc)./proc/$PID/cmdline
est la ligne de commande traitées par unexecve()
appel système pour chaque processus.c'est une meilleure solution que la plupart des upvoted: court et au point (remplacer '\000' avec des espaces à l'aide d'un outil standard)
En Python 3:
cmdline = open('/proc/PID/cmdline', 'rb').read().replace(b'\0', b' ').decode()
OriginalL'auteur Shriram V
for x; do
... par défaut, la même sémantique quefor x in "$@"; do ...
Mais le plus de la forme explicite de ... plus explicite. Juste une note de côté. 🙂OriginalL'auteur Natanael Copa
Plus souvent,
\0ctal
les séquences d'échappement sont utilisés lorsque les espaces sont inacceptables.En Bash,
printf
peut être utilisé pour ne pas encoder, par exempleOctal les fuites sont plus fréquents (et traditionnelle) dans des environnements UNIX. C'est la façon d'ajouter des espaces de chemins de montage dans /etc/fstab, par exemple.
Depuis ce paramètre pour un "produit" Webconverger, où d'autres paramètres tels que la page d'accueil webconverger.org/boot aussi être codées dans l'URL, je pense que mon choix est le meilleur.
Ensuite, vous devez utiliser un outil de traitement de texte: soit sed/perl ou un bon shell comme nouveau bash.
Eh bien, vous pourriez probablement utiliser hex échappe à la place, qui au moins ont le même nombre d'URL échappe. L'exemple devient
wlan=FOO\x20BAR
. Je pense printf sera encore de ne pas encoder.OriginalL'auteur ephemient
Vous pourriez faire quelque chose comme ce qui suit à l'aide de bash, qui serait à son tour ces arguments dans de variables comme $cmdline_union et $cmdline_wlan:
Puis vous citer et/ou d'échapper à des choses comme vous le feriez dans un shell.
OriginalL'auteur codemonkeyjohn
Puisque vous voulez le shell pour analyser le /proc/cmdline contenu, il est difficile d'éviter eval avec elle.
C'est évidemment dangereux, cependant, comme il le ferait à l'aveuglette d'exécuter tout ce qui a été spécifié sur la ligne de commande du noyau comme
quiet union=aufs wlan=FOO ) ; touch EVIL ; q=( q
.Échapper espaces (\x20) sonne comme le plus simple et sûr.
Un lourd alternative est d'utiliser un analyseur de comprendre en forme de coque de la syntaxe.
Dans ce cas, vous pourriez même pas besoin de la coquille plus.
Par exemple, avec python:
OriginalL'auteur Andrey
Dans le chic:
Vous pouvez définir une fonction et donner à votre $CMDLINE non cotées comme un argument de la fonction. Alors vous allez appeler le shell de l'analyse des mécanismes. Notez que vous devez le tester sur le shell dans lequel il va travailler dans -- zsh fait de drôles de choses à citer ;-).
Alors vous pouvez simplement demander à l'utilisateur de faire citer comme en shell:
(posh - conforme à la Politique Ordinaire Coquille, une coquille dépouillé de toutes les fonctions au-delà de la norme POSIX)
Par conséquent, comment les utilisateurs de citer une essid comme 'foo bar'? wlan=foo\040bar comme l'autre réponse? Honnêtement, je pense que le codage d'URL "%20" est plus facile pour l'utilisateur moyen que shell octal encodages.
Dans ce cas, une coquille s'échapper s'appliquent: CMDLINE="calme sans fil='foo bar bar de l'union==consommateurs et encore un autre mot' union=aufs". Mais... maintenant, je pense que si cela signifiait également que les paramètres du noyau, vous devriez plutôt utiliser octal. Le noyau ne fait pas de coquille d'expansion et pourrait être confondue voir ci-dessus wlan id.
OriginalL'auteur liori
Trouvé ici une belle façon de le faire avec awk, malheureusement il ne fonctionne que avec doublequotes:
OriginalL'auteur RedRampage
À l'aide de /proc/cmdline à partir d'un shell-script pour accéder à la ligne de commande est la mauvaise façon. Pourquoi ne pas utiliser $@?
EDIT: ajout des guillemets autour de $@.
EDIT: mal lu la question; /proc/cmdline est le noyau ligne de commande.
Rappelez-vous d'utiliser des guillemets autour de $@ ou il sera divisé dans la boucle for. L'utilisation de arg in "$@"; faire...
désolé, j'ai mal lu, comme "/proc/PID/cmdline". /proc/cmdline est la ligne de commande du noyau en cours d'exécution, et /proc/PID/cmdline est la ligne de commande de processus PID. Je ne comprends toujours pas pourquoi vous voulez analyser la ligne de commande du noyau. Je ne connais pas trop le kernel hacking", mais il semble que l'analyse /proc/cmdline de comprendre des informations sur le noyau en cours d'exécution est la mauvaise approche.
OriginalL'auteur JesperE