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 en apt-get install
. Si no obtiene esa biblioteca, solo tiene la terminación de bash primitiva estándar, por lo que, por ejemplo, si escribe apt-get i
Tabsin haberla encontrado, bash simplemente buscará los archivos en el directorio actual comenzando i
e intentará completar su comando de acuerdo con Estos nombres de archivo.
¿Por qué no está sucediendo como root?
Porque cuando lo sudo su
haces root
, la biblioteca de finalización de bash no se obtiene. Esto sería diferente si solías sudo -i
hacerte a ti mismo root
. 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 como root
, 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:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
¿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:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Dados estos argumentos, la función _quote_readline_by_ref
realiza, entre otras cosas, lo eval
mencionado anteriormente. Puedes echar un vistazo si quieres. Y cuando escribiste env $(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
[[ ${!2} == \$* ]] && eval $2=${!2}
dentro de la función _quote_readline_by_ref
en el archivo /usr/share/bash-completion/bash_completion
por la línea
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Recomiendo 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:
git clone https://salsa.debian.org/debian/bash-completion.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.
- Siéntese y espere: Tarde o temprano se lanzará una nueva versión (que incluso puede solucionar la finalización de bash dentro de la sustitución de comandos) y la obtendrá con alguna futura versión de Ubuntu. Para eso voy ;-)