bash - 带有绝对路径和控制错误的 Shell 脚本
问题描述
我正在做这个小脚本,其中第一个参数必须是现有目录的路径,第二个参数必须是其他任何东西。必须重命名第一个参数中指示的路径中的每个对象,以便新名称是作为前缀添加到作为第二个参数传递的字符串的原始名称。例如,对于字符串“hello”,对象 OBJECT1 被重命名为 hello.OBJECT1 等等
此外,如果已存在具有新名称的对象,则标准错误输出会显示一条消息,并且不会继续执行下一个对象的操作。
我做了以下事情:
#! /bin/bash
if [ "$#" != 2 ]; then
exit 1
else
echo "$2"
if [ -d "$1" ]; then
echo "directory"
for i in $(ls "$1")
do
for j in $(ls "$1")
do
echo "$i"
if [ "$j" = "$2"."$i" ]; then
exit 1
else
mv -v "$i" "$2"."$i"
echo "$2"."$i"
fi
done
done
else
echo "no"
fi
fi
如果我从另一个文件而不是我想要执行的文件运行脚本,我会遇到问题,例如,如果我在 /home/pp 中并且我希望在 /home/pp/rr 中进行更改,因为那是它在当前所做的唯一方法。
我试图更改 ls 以使用 ls -R | 捕捉整个路线 sed "s;^; pwd
;" 但这条路线让我很受不了。
使用 find 你不能因为它把我放在路径前面并且不会离开文件
然后是另一个问题,为了验证将要创建新的对象不在内部,当使用两个 for 执行此操作时,我得到所有文件的 bash 错误,而不仅仅是巧合
我从这个脚本开始,所以它必须是一个非常简单的解决方案
解决方案
您的问题的一个明显答案是cd "$2
在脚本中添加 a 以使其工作。但是,此脚本中有一些改进的机会。
#! /bin/bash
if [ "$#" != 2 ]; then
例如,您可能会在此处输入错误消息,echo "Usage: $0 dir prefix"
或者甚至是更详细的帮助文本。
exit 1
else
echo $2
请引用,如echo "$2"
.
if [ -d $1 ]; then
在这里,引号很重要。假设您的目录名称中有一个空格;那么这个 if 会失败bash: [: a: binary operator expected
。因此,在 $1 周围加上引号:if [ -d "$1" ]; then
echo "directory"
这是您可以插入cd "$1"
.
for i in $(ls $1)
do
解析的输出几乎总是一个坏主意ls
。同样,如果文件名中有空格,则此 for 循环将失败。一个可能的改进是for i in "$1"/* ; do
。
for j in $(ls $1)
do
echo $i
if [ $j = $2.$i ]; then
exit 1
else
这部分的逻辑似乎是:如果存在带有前缀的文件,则退出而不是覆盖。说明脚本失败的原因总是一个好主意。echo
前一个会有exit 1
帮助。
问题是你为什么使用第二个循环?一个简单的if [ -f "$2.$i ] ; then
会做同样的事情,但没有第二个循环。因此它会更快。
mv -v $i $2.$i
echo $2.$i
再次:使用引号!
fi
done
done
else
echo "no"
fi
fi
因此,有了所有的评论,您应该能够改进您的脚本。正如 Tripleee 在他的评论中所说,运行 shellcheck 会为您提供上面的大部分评论。但他也提到basename
了,这在这里很有用。
有了这一切,这就是我要做的事情。当您需要对脚本进行一些更改并尝试记住您过去的逻辑时,您可能只会在几个月后欣赏一些更改。
#!/bin/bash
if [ "$#" != 2 ]; then
echo "Usage: $0 directory prefix" >&2
echo "Put a prefix to all the files in a directory." >&2
exit 1
else
directory="$1"
prefix="$2"
if [ -d "$directory" ]; then
for f in "$directory"/* ; do
base=$(basename "$f")
if [ -f "Sdirectory/$prefix.$base" ] ; then
echo "This would overwrite $prefix.$base; exiting" >&2
exit 1
else
mv -v "$directory/$base" "$directory/$prefix.$base"
fi
done
else
echo "$directory is not a directory" >&2
fi
fi
推荐阅读
- python - sqlalchemy:不同表的相同基础
- javascript - 如何设置动态创建的默认下载文件名
- go - 一个全局函数中的多个 GOLANG 函数
- typescript - 我可以在我的应用关闭时启动电子更新器更新吗?
- c# - MongoDb .NET 映射继承的类成员
- cuda - 禁用 CUDA 编译器驱动程序的二进制缓存
- unit-testing - 在本机环境中使用 PlatformIO 进行 Unity 测试 - 没有 avr-gcc 库
- video - ffmepg - 当我运行第二个实例时,第一个停止
- reactjs - ReactJS 重新渲染太多。React 限制渲染次数以防止无限循环
- java - 使用轮廓检测不完整/破圆