No puedo cambiar el directorio en el script usando variables

No puedo cambiar el directorio en el script usando variables

Mi guión:

#!/bin/sh

_directory1="/home/user/test1"
_directory2="test2"

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

Y aquí está el error:

./myscript.sh: 6: cd: can't cd to /home/user/test1/test2

¿Qué estoy haciendo mal?

Respuesta1

Su código original antes de las ediciones:

#!/bin/sh

_directory1="~/test1"
_directory2="test2"

for i in $(cd "${_directory1}/$_directory2")
do
    echo "$i"
done
  1. La tilde ( ~) no se comporta como una variable. Por ejemplo, no se expandirá a la ruta de su directorio personal cuando se use entre comillas. En un guión, utilice $HOMEen lugar de tilde. ~es un "atajo" que quizás desee utilizar en la línea de comando, pero $HOMEes más descriptivo en un script.

  2. cdno genera nada que pueda recorrer, por lo que usarlo cden una sustitución de comando forno le servirá de nada. Desafortunadamente, no está claro qué desea que haga realmente su bucle, por lo que no puedo ofrecerle una implementación alternativa segura.


El código con tus ediciones:

#!/bin/sh

_directory1="/home/user/test1"
_directory2="test2"

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

Este código solo generaría

"./myscript.sh: 6: cd: can't cd to /test2"

si escribe mal el nombre de la variable _directory1(y la variable mal escrita está vacía y el /test2directorio no existe).


Luego editaste el mensaje de error.de nuevodecir que produce

./myscript.sh: 6: cd: can't cd to /home/user/test1/test2

lo que simplemente significa que el directorio /home/user/test1/test2no existe. No ha dado pruebas de que este directoriohaceexisten, por lo que tenemos que confiar en la palabra de su sistema al respecto.


Aquí hay un script que enumera el contenido de un directorio (suponiendo que el directorio exista). El código imprime la ruta completa de cada archivo.

#!/bin/bash

topdir=$HOME/test1
subdir=test2

printf '%s\n' "$topdir/$subdir"/*

O,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

for name in "$topdir/$subdir"/*; do
    printf '%s\n' "$name"
done

La nullglobopción Shell hace que el bucle no se ejecute en absoluto si el patrón dado no coincide con nada. Sin configurar la nullglobopción, el patrón permanecería sin expandir si no coincidiera con nada, y el bucle lo usaría como valor $nameen una sola iteración.

También es posible que desee configurar la dotglobopción de shell ( shopt -s dotglob) si está interesado en nombres ocultos (nombres de archivos que comienzan con un .carácter).

O, sin imprimir la ruta completa a cada nombre de archivo,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

cd "$topdir/$subdir" || exit 1

printf '%s\n' *

Terminará exit 1el script si cdfalla.

O,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

cd "$topdir/$subdir" || exit 1

shopt -s nullglob

for name in *; do
    printf '%s\n' "$name"
done

Para imprimir solo los nombres de archivos sin su ruta completa, sin usar cd:

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

for name in "$topdir/$subdir"/*; do
    printf '%s\n' "$( basename "$name" )"

    # or:  printf '%s\n' "${name##*/}"

done

Esto utiliza la basenameutilidad para extraer solo la parte del nombre de archivo de las rutas. La alternativa en el comentario utiliza una sustitución de parámetro estándar, ${name##*/}, para eliminar la ruta del directorio inicial antes de los nombres de archivo (literalmente "eliminar la cadena de prefijo más larga que coincida con el patrón */de $name").

información relacionada