Ich kann das Verzeichnis im Skript mithilfe von Variablen nicht ändern

Ich kann das Verzeichnis im Skript mithilfe von Variablen nicht ändern

Mein Skript:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

Und hier ist der Fehler:

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

Was mache ich falsch?

Antwort1

Ihr Originalcode vor den Änderungen:

#!/bin/sh

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

for i in $(cd "${_directory1}/$_directory2")
do
    echo "$i"
done
  1. Die Tilde ( ~) verhält sich nicht wie eine Variable. Sie wird beispielsweise nicht in den Pfad zu Ihrem Home-Verzeichnis erweitert, wenn sie in Anführungszeichen verwendet wird. Verwenden Sie in einem Skript $HOMEanstelle der Tilde. ~ist eine „Abkürzung“, die Sie möglicherweise in der Befehlszeile verwenden möchten, die $HOMEin einem Skript jedoch aussagekräftiger ist.

  2. cdgibt nichts aus, das Sie durchlaufen können, daher bringt Ihnen die Verwendung cdin einer Befehlsersetzung fornichts. Leider ist unklar, was Ihre Schleife eigentlich tun soll, daher kann ich Ihnen keine todsichere alternative Implementierung geben.


Der Code mit Ihren Änderungen:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

Dieser Code würde nur

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

wenn Sie den Namen der Variablen falsch schreiben _directory1(und die falsch geschriebene Variable leer ist und das /test2Verzeichnis nicht existiert).


Anschließend haben Sie die Fehlermeldung bearbeitetwiederzu sagen, dass es ausgibt

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

was einfach bedeutet, dass das Verzeichnis /home/user/test1/test2nicht existiert. Sie haben keinen Beweis dafür erbracht, dass dieses Verzeichnistutexistieren, also müssen wir uns diesbezüglich auf das Wort Ihres Systems verlassen.


Hier ist ein Skript, das den Inhalt eines Verzeichnisses auflistet (vorausgesetzt, das Verzeichnis existiert). Der Code druckt den vollständigen Pfadnamen jeder Datei.

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

Oder,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

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

Die nullglobShell-Option bewirkt, dass die Schleife überhaupt nicht ausgeführt wird, wenn das angegebene Muster nicht übereinstimmt. Ohne die nullglobOption würde das Muster unerweitert bleiben, wenn es nicht übereinstimmt, und die Schleife würde es in einer einzigen Iteration als Wert verwenden $name.

Wenn Sie an versteckten Namen (Dateinamen, die mit einem Buchstaben beginnen) interessiert sind, können Sie auch die dotglobShell-Option ( ) festlegen .shopt -s dotglob.

Oder, ohne den vollständigen Pfad zu jedem Dateinamen auszudrucken,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

printf '%s\n' *

exit 1Wenn dies fehlschlägt, wird das Skript beendet cd.

Oder,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

shopt -s nullglob

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

Um nur die Dateinamen ohne den vollständigen Pfad auszudrucken, ohne Folgendes zu verwenden 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

Dies verwendet das basenameDienstprogramm, um nur den Dateinamenteil der Pfadnamen zu extrahieren. Die Alternative im Kommentar verwendet eine Standardparametersubstitution, ${name##*/}um den anfänglichen Verzeichnispfad vor den Dateinamen zu löschen (wörtlich „entfernen Sie die längste Präfixzeichenfolge, die dem Muster entspricht, */aus $name“).

verwandte Informationen