Não consigo alterar o diretório no script usando variáveis

Não consigo alterar o diretório no script usando variáveis

Meu roteiro:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

E aqui está o erro:

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

O que estou fazendo de errado?

Responder1

Seu código original antes das edições:

#!/bin/sh

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

for i in $(cd "${_directory1}/$_directory2")
do
    echo "$i"
done
  1. O til( ~) não se comporta como uma variável. Ele não será, por exemplo, expandido para o caminho do seu diretório inicial quando usado entre aspas. Em um script, use $HOMEem vez de til. ~é um "atalho" que você pode usar na linha de comando, mas $HOMEé mais descritivo em um script.

  2. cdnão produz nada que você possa fazer um loop, portanto, usar cduma substituição de comando com fornão fará nada de bom. Infelizmente, não está claro o que você deseja que seu loop realmente faça, então não posso fornecer uma implementação alternativa infalível.


O código com suas edições:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

Este código só geraria

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

se você digitar incorretamente o nome da variável _directory1(e a variável incorreta estiver vazia e o /test2diretório não existir).


Você então editou a mensagem de errode novodizer que isso produz

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

o que significa simplesmente que o diretório /home/user/test1/test2não existe. Você não forneceu evidências de que este diretóriofazexistem, então temos que acreditar na palavra do seu sistema quanto a isso.


Aqui está um script que lista o conteúdo de um diretório (assumindo que o diretório existe). O código imprime o nome do caminho completo de cada arquivo.

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

Ou,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

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

A nullglobopção shell faz com que o loop não seja executado se o padrão fornecido não corresponder a nada. Sem definir a nullglobopção, o padrão permaneceria sem expansão se não correspondesse a nada, e o loop o usaria como valor $nameem uma única iteração.

Você também pode querer definir a dotglobopção shell ( shopt -s dotglob) se estiver interessado em nomes ocultos (nomes de arquivos começando com um .caractere).

Ou, sem imprimir o caminho completo para cada nome de arquivo,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

printf '%s\n' *

O exit 1encerrará o script se cdfalhar.

Ou,

#!/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 apenas os nomes dos arquivos sem o caminho completo, sem 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

Isso usa o basenameutilitário para extrair apenas a parte do nome do arquivo dos nomes de caminho. A alternativa no comentário usa uma substituição de parâmetro padrão, ${name##*/}para excluir o caminho do diretório inicial antes dos nomes dos arquivos (literalmente "remover a string de prefixo mais longa que corresponda ao padrão */de $name").

informação relacionada