我無法使用變數更改腳本中的目錄

我無法使用變數更改腳本中的目錄

我的腳本:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

這是錯誤:

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

我究竟做錯了什麼?

答案1

編輯前的原始程式碼:

#!/bin/sh

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

for i in $(cd "${_directory1}/$_directory2")
do
    echo "$i"
done
  1. 波形符 ( ~) 的行為與變數不同。例如,當在引號中使用時,它不會擴展到主目錄的路徑。在腳本中,使用$HOME波浪號代替。~是您可能想在命令列上使用的“快捷方式”,但$HOME在腳本中更具描述性。

  2. cd不會輸出任何可以循環的內容,因此cd在命令替換中使用 withfor不會為您帶來任何好處。不幸的是,目前還不清楚您希望循環實際執行什麼操作,因此我無法為您提供可靠的替代實作。


包含您編輯的程式碼:

#!/bin/sh

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

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

這段程式碼只會輸出

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

如果變數名稱拼字錯誤_directory1(且拼字錯誤的變數為空,且/test2目錄不存在)。


然後您編輯了錯誤訊息再次說它輸出

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

這僅僅意味著該目錄/home/user/test1/test2不存在。您還沒有提供證據證明目錄存在,所以我們必須相信您的系統的說法。


這是一個列出目錄內容的腳本(假設該目錄存在)。程式碼列印每個檔案的完整路徑名。

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

或者,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

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

如果給定的模式與任何內容都不匹配, shellnullglob選項將使循環根本不運行。如果不設定該nullglob選項,如果 if 不符合任何內容,則模式將保持未展開狀態,並且循環將$name在單次迭代中使用它作為 for 的值。

如果您對隱藏名稱(以字元開頭的檔案名稱)感興趣,您可能還需要設定dotglobshell 選項 ( )。shopt -s dotglob.

或者,不列印每個檔案名稱的完整路徑,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

printf '%s\n' *

如果失敗,將exit 1終止腳本cd

或者,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

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

shopt -s nullglob

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

若要僅列印檔案名稱而不列印完整路徑,而不使用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

這使用該basename實用程式僅提取路徑名的檔案名稱部分。註解中的替代方法使用標準參數替換來刪除檔案名稱之前的初始目錄路徑(字面意思是「刪除與${name##*/}模式相符的最長前綴字串」)。*/$name

相關內容