Unset variable en lecture seule dans bash
comment faire pour annuler la lecture seule variable en Bash?
$ readonly PI=3.14
$ unset PI
bash: PI: readonly variable
ou n'est-il pas possible?
- ah mon mauvais tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_01.html Faire de variables en lecture seule. Ces variables ne peuvent pas être affectés de valeurs par la suite des instructions d'affectation, ils ne peuvent être annuler.
- Généralement, les variables sont en lecture seule car /etc/profile contient beaucoup de lignes comme ceci
readonly TMOUT
. Je préfère commenter ces lignes et à ouvrir une nouvelle connexion à cette machine Linux. - Ou, tout simplement exec bash --norc, puis définissez les trucs que vous ne voulez manuellement, ou dans votre propre fichier rc - par exemple: source ~/.gnbashrc
Vous devez vous connecter pour publier un commentaire.
En fait, vous pouvez désactiver une variable en lecture seule. mais je dois vous avertir que c'est un hacky méthode. L'ajout de cette réponse, qu'à titre d'information, non pas comme une recommandation. Utilisez à votre propre risque. Testé sur ubuntu 13.04, bash 4.2.45.
Cette méthode implique de connaître un peu de bash code source & c'est héritée de cette réponse.
Un oneliner réponse est d'utiliser le traitement par lots et d'autres de ligne de commande de drapeaux, comme le prévoit la F. Hauri réponse:
sudo
peut ou peut ne pas être nécessaire en fonction de votre noyau est ptrace_scope paramètres. Vérifier les commentaires sur vip9937 la réponse pour plus de détails.cat << EOF| sudo gdb
àsudo gdb << EOF
. peut pas de travail, depuis la redirection de l'entrée de fournisseurbash
est arrêté en raison d'gdb
pièce jointe.gdb
en mode script pourrait être utile si de nombreuxattach
ont à faire. Pour uniq processus, l'utilisation--pid
drapeau... et pour une seule commande, u pourrait utiliser-ex
, voir ma réponse: quelque Chose commegdb -ex 'call unbind_variable("PI")' --pid=$$ --batch
pourrait être suffisant.echo -e "attach $$\n call unbind_variable(\"PI\")\n detach" | gdb
J'ai essayé le gdb hack ci-dessus parce que je veux annuler TMOUT (pour désactiver la déconnexion automatique), mais sur la machine qui a TMOUT en lecture seule, je n'ai pas le droit d'utiliser sudo. Mais depuis que je possède le bash processus, je n'ai pas besoin de sudo. Toutefois, la syntaxe n'a pas assez de travail avec la machine, j'en suis sur.
Ce n'travail, même si (je l'ai mis dans mon .bashrc fichier):
-q -n
options de silencegdb
une charge pas de .gdbinit fichier par sécurité./proc/sys/kernel/yama/ptrace_scope
. Les valeurs les plus courantes sont0
, dans ce cas, vous pouvez le faire, et1
, dans lequel cas, vous ne pouvez probablement pas commegdb
n'est pas le parent direct de labash
processus en cours de débogage.-q
et-n
sont utiles, elles (à savoir-q
) ne pas garder le silencegdb
, de sorte que le/dev/null
redirection est toujours nécessaire. Très bonne suggestion si, @LucasCimonunset
ilSelon la page de man:
Si vous n'avez pas encore exporté de la variable, vous pouvez utiliser
exec "$0" "$@"
pour redémarrer votre shell, bien sûr, vous perdrez toutes les autres de l'onu-exporté variables ainsi. Il semble que si vous démarrez un nouveau shell sansexec
, il perd de sa propriété en lecture seule pour que le shell.Peu de temps: inspiré par anishsane réponse
Mais avec de plus simple syntaxe:
De quelques améliorations, comme une fonction:
Mon
destroy
fonction:Ou Comment jouer avec la variable de méta-données. Remarque l'utilisation d'une rare bashisms:
local -n VARIABLE=$1
et${VARIABLE@a}
...Vous pouvez copier à un bash fichier source appelé
destroy.bash
, par exemple...Explication:
$flags
.unset
au lieu degdb
si en lecture seule drapeau présente pas dewhile read ... result= ... done
obtenir le code retour de lacall unbind
dansgdb
sortiegdb
syntaxe avec l'utilisation de--pid
et--ex
(voirgdb --help
).$result
decall unbind
commande.En cours d'utilisation:
L'utilisation de GDB est terriblement lent. Essayez ctypes.sh au lieu de cela. Il fonctionne en utilisant libffi pour appeler directement bash est unbind_variable() à la place, qui est tout aussi rapide que tout autre bash builtin:
D'abord, vous aurez besoin d'installer le ctypes.sh:
Voir https://github.com/taviso/ctypes.sh pour une description complète et docs.
Pour les curieux, oui, cela vous permet d'appeler n'importe quelle fonction à l'intérieur de bash, ou de toute fonction dans une bibliothèque liée à bash, ou même externes chargées dynamiquement de la bibliothèque si vous le souhaitez. Bash est maintenant tout aussi dangereux que perl... 😉
include ctypes.sh
vous diresource ctypes.sh
ou. ctypes.sh
.Spécifiquement wrt pour le TMOUT variable. Une autre option, si gdb n'est pas disponible pour copier bash dans votre répertoire home et patch le TMOUT chaîne dans le binaire à autre chose, par exemple XMOUX. Et puis exécutez cette couche supplémentaire de shell et vous ne serez pas expiré.
readonly commande définitive et permanente jusqu'à ce que le processus de shell se termine. Si vous avez besoin de changer une variable, ne pas marquer en lecture seule.
Non, pas dans le shell courant. Si vous souhaitez affecter une nouvelle valeur à elle, vous aurez la fourche à la fourchette un nouveau shell où il aura un nouveau sens et ne sera pas considéré comme
read only
.Dans zsh,
(Oui, je sais que la question dit bash. Mais quand vous faites une recherche Google pour zsh, vous obtenez également un tas de bash questions.)
Vous ne pouvez pas, à partir de la page de manuel de
unset
:typeset +r VAR
ne marche pas puisque, aussi en fonction de la page de man,Using '+' instead of '-' turns off the attribute instead, with the exception that +a may not be used to destroy an array variable.
Une autre façon de "détruire" lecture seule variable Bash est à déclarer la variable en lecture seule dans un jetable contexte:
Alors que ce n'est pas "la suppression de" à l'intérieur de la portée, ce qui est probablement l'intention de l'auteur original, c'est vraiment la définition d'une variable en lecture seule à partir du point de vue de baz (), puis plus tard, rendant la lecture-écriture à partir du point de vue de baz(), il vous suffit d'écrire votre script avec une certaine perspicacité.
Quoi faire maintenant?
Un shell interne est exécuté peut hériter d'un parent est de variables, mais ne pas hériter de leur statut de protection.
Une alternative si gdb n'est pas disponible: Vous pouvez utiliser le
activer
commande pour charger une coutume builtin qui vous permettra de désactiver l'attribut en lecture seule. L'essentiel du code qui le fait:Évidemment, vous souhaitez remplacer
TMOUT
avec la variable que vous vous souciez.Si vous ne voulez pas tourner que dans un builtin vous-même, je bifurquais bash sur GitHub et a ajouté une entièrement écrit et prêt-à-compiler chargeable builtin appelé
readwrite
. La livraison est à https://github.com/josephcsible/bash/commit/bcec716f4ca958e9c55a976050947d2327bcc195. Si vous voulez l'utiliser, obtenir la source de Bash avec mon commit, exécutez./configure && make loadables
pour le construire, puisenable -f examples/loadables/readwrite readwrite
pour l'ajouter à votre session en cours d'exécution, puisreadwrite TMOUT
de l'utiliser.