¿Cómo puedo proteger paréntesis pasados ​​a un comando de cd? [duplicar]

18

Le pregunté aquí cómo hacer que cd proteja espacios. La finalización de pestañas es excelente, pero a veces se pega la ruta desde el portapapeles, por lo que es útil.

Sin embargo, la solución rompe con paréntesis. No importa cómo intentes escapar y proteger la entrada, siempre regresa:

bash: syntax error near unexpected token '('

¿Hay alguna forma de que también tenga que ver con paréntesis? Lo que quiero es que cuando entro en esto, funcione:

cd My path with spaces (and parentheses)
    
pregunta Strapakowsky 30.03.2013 - 01:35

2 respuestas

18

Use comillas simples ' alrededor del argumento. (Esto funciona para cualquier comando, no solo cd ).

cd 'My path with spaces (and parentheses)'

No puedes hacer que bash pase el paréntesis a cd . Hacer que los espacios funcionen es un truco muy especializado.

Las comillas simples funcionan alrededor de cada carácter, excepto ' . Reemplazar comillas simples por la secuencia de 4 caracteres '\'' .

cd 'Apostrophe'\''s a pain'

Esto no funciona si el nombre del directorio comienza con un guión, porque eso hace que el comando cd interprete el argumento como una opción. Pase -- antes del nombre del directorio para evitar esto.

Ver enlace para más detalles.

Otro método es hacer que el shell lea una línea de texto separada en lugar de pasar el argumento en la línea de comando.

Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$ 

En lugar de copiar y pegar manualmente, también podría hacerlo programáticamente. Instale xclip o xsel .

cd -- "$(xclip -o -selection clipboard)"
cd -- "$(xsel -bo)"

Puede hacer que este sea un alias.

alias cde='cd -- "$(xsel -bo)"'
    
respondido por el Gilles 30.03.2013 - 02:14
6

Cómo correctamente cd a directorios con caracteres como espacios y paréntesis en sus nombres:

Si el nombre de su carpeta no incluye un carácter de comillas simples ' , simplemente enciérrelo entre comillas simples:

cd 'My path with spaces (and parentheses)'

Si incluye un ' , pero no incluye un carácter de comillas dobles " , un backlash \ , un backquote ' o un% $ , enciérrelo entre comillas dobles:

cd "My path with spaces (and parentheses)"

No es muy común que un nombre de archivo o directorio contenga comillas simples o dobles. (Esto quizás se deba a que no es común que un archivo o nombre de directorio contenga comillas dobles. La única razón por la que no recomendé comillas dobles originalmente es que, a diferencia de las comillas simples, las comillas dobles permiten que $ se expanda variables de entorno. Esto sería un problema si tu nombre de archivo contiene un carácter $ seguido de texto.)

Si contiene ambos, o simplemente quiere otro método, puede escaparse de cada espacio y paréntesis manualmente insertando un carácter de barra diagonal \ antes de él:

cd My\ path\ with\ spaces\ \(and parentheses\)

Eso es molesto, pero afortunadamente, el shell con lo hace por ti , si escribes el comienzo del nombre y presionas Tab . Si hay más de un nombre de archivo o directorio que comienza con My , entonces es posible que deba escribir más para que se expanda. Si presiona Tab y no se expande, puede presionar Tab nuevamente para ver una lista de archivos que coinciden con lo que ha tipeado hasta ahora. Entonces sabrá cuánto más debe escribir para que coincida de manera única y expandir.

Alternativamente, podría escapar de las comillas internas. Por ejemplo, supongamos que tiene una carpeta llamada:

Mischa's gardening tips for "home and office"

Puede usar:

cd Mischa\'s\ gardening\ tips\ for\ \"home\ and\ office\"

Pero también puedes usar:

cd 'Mischa'\''s gardening tips for "home and office"'

Las barras diagonales inversas no son especiales dentro de comillas simples, por lo que terminamos la cadena entre comillas simples, anexamos una comilla simple protegida contra barra invertida e inmediatamente iniciamos otra cadena entre comillas simples, todo sin ningún espacio que inicie un argumento separado.

Por qué probablemente no puedas hacer que cd funcione de la forma que quisieras:

En cuanto a que funcione cd My path with spaces (and parentheses) : no, realmente no se puede hacer eso, porque este comportamiento no es específico del comando cd , es parte del funcionamiento de cualquier comando. Cuando se ejecuta un comando, se proporciona una lista de argumentos proporcionados por el usuario. Cuando el proyectil ve un espacio, sabe que un argumento acaba de terminar y otro acaba de comenzar. Para pasar un espacio como parte de un argumento, debe citarse en una de las formas anteriores.

Podrías lograr parte de este algún tiempo - podrías hacer que cd My path with spaces trabaje para ir a la carpeta My path with spaces . Puede lograr esto escribiendo un script de shell que concatena todos los argumentos provistos por el usuario con espacios. (Entonces, si lo desea, puede hacer que cd llame a esa secuencia de comandos, creando un alias de shell llamado cd para ella, que tendrá prioridad sobre la shell incorporada cd que actualmente está ejecutando normalmente). Pero:

  • El script no recibiría argumentos diferentes para My path with spaces y My path with spaces , por lo que cd My path with spaces fallaría o ingresaría en la carpeta incorrecta.

  • No podría hacer esto para los paréntesis, ya que se usan para la agrupación por el shell de modo que no se comuniquen de ningún modo con un comando. En realidad, la mayoría de las veces el shell simplemente lanzará un error de sintaxis (tal como lo ha visto):

    ek@Kip:~$ cd My path with spaces (and parentheses)
    bash: syntax error near unexpected token '('
    

    No importa lo que cambie, ese error de sintaxis continuará ocurriendo cuando se dé ese comando.

Digo que "probablemente" no puede hacer que esto funcione porque hay una manera en que lo hará: puede hacer su propio caparazón que se comporte como lo desee. Pero esto es extremadamente difícil y es poco probable que alguien quiera hacer eso, solo para hacer este cambio. (También podría modificar el código fuente de un shell existente, que es una solución más práctica, pero aún requiere más esfuerzo de lo que la mayoría de la gente querría ejercer.) Además de eso, es poco probable que cd acepte nombres de directorio con caracteres arbitrarios, incluidos espacios en ellos, como lo hace en Windows.

En caso de que se pregunte por qué funciona esto en Windows, pero no en Ubuntu: en Windows, los comandos pasan el texto escrito como una cadena de texto y cuando un comando necesita interpretar esa cadena como una secuencia de argumentos separados (que generalmente, pero no siempre), el código para el comando debe llamar a una función de biblioteca especial que analiza la cadena de línea de comandos. (En un programa C, esto ocurre detrás de escena, pero aún implica el uso de la API de Windows).

    
respondido por el Eliah Kagan 30.03.2013 - 02:05

Lea otras preguntas en las etiquetas