我无法使用变量更改脚本中的目录

我无法使用变量更改脚本中的目录

我的脚本:

#!/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”)。

相关内容