Estoy tratando de entrar en una irb
sesión con variables de entorno específicas de un archivo con este comando:
$ env $(cat env.sh) irb
Pero cuando intento presionar Tab
después de escribir env.
para completarlo, aparece el siguiente error:
$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file
Otra cosa interesante es que si estoy conectado como root, este error no ocurre.
Aquí está la salida de find ~ -uid 0
:
$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003
¿Alguien puede explicarme por qué sucede esto y, si es así, cómo lo soluciono cuando no soy un usuario root?
command-line
bash
auto-completion
eldosoa
fuente
fuente
sudo su
.find ~ -uid 0
.~
es/home/something
.Respuestas:
Encontraste un error en la biblioteca Bash Completion utilizada por Ubuntu.
¿Qué significa esto?
Ubuntu utiliza una biblioteca de finalización de bash para hacer que la finalización de bash sea inteligente. Esta biblioteca vive en
/usr/share/bash-completion/bash_completion
.Esencialmente, esta biblioteca declara algunas funciones inteligentes que conocen los comandos típicos y cómo completarlos. Cada vez que presiona Tab, se llama a las funciones dentro de esta biblioteca e intenta completar su línea de comando actual. Entonces, por ejemplo, si escribe
apt-get i
Tab, completará eso enapt-get install
. Si no obtiene esa biblioteca, solo tiene la terminación de bash primitiva estándar, por lo que, por ejemplo, si escribeapt-get i
Tabsin haberla encontrado, bash simplemente buscará los archivos en el directorio actual comenzandoi
e intentará completar su comando de acuerdo con Estos nombres de archivo.¿Por qué no está sucediendo como root?
Porque cuando lo
sudo su
hacesroot
, la biblioteca de finalización de bash no se obtiene. Esto sería diferente si solíassudo -i
hacerte a ti mismoroot
. Apuesto a que ves el error, ¿no? Vea, por ejemplo, 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash': ¿cuándo importa cuál se usa o si importa? Si no estás familiarizado con las diferencias.En mi caso, como usuario normal, la biblioteca se obtiene cuando inicio un shell Bash porque las
~/.bashrc
fuentes de/etc/bash_completion
las fuentes/usr/share/bash-completion/bash_completion
.Si uso
sudo -i
para iniciar sesión comoroot
, la biblioteca se obtiene porque las/etc/profile
fuentes de/etc/profile.d/bash_completion.sh
las fuentes/usr/share/bash-completion/bash_completion
.¿Por qué está ocurriendo ese error?
Intenta ejecutar este comando:
¿Luce familiar? ;-) De hecho, eso es exactamente lo que sucedió detrás de escena cuando tocaste Taben el contexto que describiste. Más precisamente, el error está en la función
_quote_readline_by_ref
declarada por/usr/share/bash-completion/bash_completion
. Si obtuvo ese archivo, debería tener esa función disponible. Entonces, intente esto:Dados estos argumentos, la función
_quote_readline_by_ref
realiza, entre otras cosas, loeval
mencionado anteriormente. Puedes echar un vistazo si quieres. Y cuando escribisteenv $(cat env.
Tab, detrás de escena esa función fue llamada exactamente con esos argumentos. Entonces eso fue lo que pasó.Se suponía que este
eval
truco solucionaría otro problema , pero supongo que introdujo este otro error en el proceso.¿Cómo lo soluciono?
Resulta que este error ya ha sido reportado . Después de leer ese informe de error, veo tres formas de solucionarlo:
Parcheo: en uno de los comentarios en ese informe de error, alguien sugiere reemplazar la línea
dentro de la función
_quote_readline_by_ref
en el archivo/usr/share/bash-completion/bash_completion
por la líneaRecomiendo no hacer esto. La persona que escribió ese comentario no parece ser un desarrollador de bash-complete . Esta revisión simplemente hará que el operando izquierdo de la instrucción se evalúe como falso y, por lo tanto, evitará que eso
eval
suceda. Sin embargo, sin un buen conocimiento de lo que se supone que debe hacer esa función y en qué contextos se llama, no está claro si esto no romperá potencialmente alguna otra funcionalidad prevista.Obtenga la versión más reciente: como también se mencionó en ese informe de error, este error no está presente en git head (en donde, entre otros cambios, la función
_quote_readline_by_ref
se ha simplificado). Simplemente puede clonar la revisión actual desde Git:... y luego copie la versión más reciente de la
bash_completion
secuencia de comandos a/usr/share/bash-completion
(no hay necesidad urgente de hacer una copia de seguridad de la versión anterior a menos que lo haga sentir más seguro; si experimenta algunos problemas,sudo apt-get install --reinstall bash-completion
debería revertir cualquier cambio que haya hecho). Esta es la forma en que yo recomiende si tiene prisa para arreglar esto. :-)Tenga en cuenta que ninguna de esas soluciones hará que la finalización de bash funcione dentro de la sustitución de comandos: como se menciona en el mismo informe de error, esto se rompe en Bash 4.3.
fuente
sudo su
para convertirse en root, no obtiene la biblioteca, pero en su lugar se obtendrá cuando se usasudo -i
, que es la forma prevista de obtener una sesión raíz interactiva. En cuanto a su pregunta: dado que cualquier shell bash lee lo~/.bashrc
que eventualmente obtiene la biblioteca, y no hay forma de "des-fuente" de un archivo, no veo una manera completamente directa. Aquí hay un posible truco: haga que el abastecimiento de la biblioteca esté condicionado a alguna variable de entorno, por ejemploNOCOMPL
, no se define en su~/.bashrc
...