我正在尝试使用 cmake 和 OpenGL 来学习计算机图形学,并且该教程包含一个 run.sh 文件,该文件应该编译/构建 cpp 程序。这是代码:
#!/bin/bash
#calls cd build
#cmake .. -DSRC<argument> && make argument
EMBEDDED=`echo $2`
DIRECTORY=`echo $1 |cut -d'/' -f1`
FILENAME=`echo $1 |cut -d'/' -f2 |cut -d'.' -f1 | sed -e "s|/|_|g"`
TARGET=${FILENAME}
mkdir build
cd build
rm bin/${TARGET}
cmake .. -DSRC=../$1
make VERBOSE=1
bin/${TARGET}
根据我的理解, mkdir 创建一个构建目录,然后我们“cd”到该目录,从以前的构建中删除一些内容,cmake实际文件,我不知道 make“VERBOSE=1” 做了什么,然后我想我们访问最后一行中的可执行文件。
我不明白以 EMBEDDED 开头的中间代码块的作用,我也不确定第三个注释“#cmake ...”的作用。我正在使用 cpp 文件,并且我认为我必须将该文件作为命令行参数与 ./run.sh 一起传递。
答案1
作业过于复杂
EMBEDDED=`echo $2`
这需要脚本的第二个参数对其执行 split 和 glob(惊讶!)并将其结果传递给echo
,然后分配任何所做的结果echo
(由于蠕动的特征主义,可能不是回声) 到EMBEDDED
。使用简单的写法可能更明智
EMBEDDED=$2
赋值语句。
过于复杂的文件路径组件确定
DIRECTORY=`echo $1 |cut -d'/' -f1`
这可以使用dirname(1)
命令 with 来更仔细地编写,还""
可以消除 POSIX split 和 glob,因为人们可能不希望(惊讶!) split 和 glob 产生任何结果,从而将分配给 的内容弄脏DIRECTORY
。
DIRECTORY=`dirname "$1"`
但是,dirname
和cut -d'/' -f1
并不相同,除非唯一的输入是somedirectory/somefile
。有人需要了解代码的输入才能知道是否dirname
可以进行简化。预期的输入没有记录在问题中发布的脚本中 - 它们是否记录在任何地方?
在相关说明中,有一个basename(1)
命令可能会有所帮助
FILENAME=`echo $1 |cut -d'/' -f2 |cut -d'.' -f1 | sed -e "s|/|_|g"`
尽管这条管道似乎试图从cut -d'.' -f1
获取 a ,但我不知道它的用途,因为它不能出现在文件名中。如果传递的参数中有 ,那么将它们作为传递而不是添加额外的代码来更改为会更明智。所以上面的内容可能可以简化为prefix
prefix.whatever
sed -e "s|/|_|g"
/
_
_
/
_
FILENAME=`basename "$1" | cut -d'.' -f1`
不必要的危险命令
mkdir build
cd build
rm bin/${TARGET}
此序列可能会也可能不会创建目录,然后将尝试从新目录或失败时从该目录的父目录中build
删除各种内容。build
这是草率且不确定的。我所说的各种事情的意思是,它将${TARGET}
通过 POSIX shell split 和 glob 进行扩展,因此可能包含非常意外的文件名 - 幸运的是,这rm
不是通常的“哦,是的,关于你刚刚丢失的文件系统”,rm -rf
因此欢闹将仅限于各种(仍然令人惊讶!)文件名,可能来自错误的目录。
(有些人可能会认为配置管理或至少受保护的命令应该使用而不是脆弱且容易出错的 shell 脚本,但我们在这里......)
[ -d build ] || { mkdir build; [ -d build ] || exit 1; }
cd build || exit 1
rm bin/"${TARGET}"
cmake .. -DSRC=../"$1" && make VERBOSE=1 && bin/"${TARGET}"
这build
是一个目录,被制作为目录,或者脚本失败(您也可以添加自定义错误消息,尽管mkdir
通常会产生噪音)。这不是原子的,因为检查和后续touch build
之间可能存在其他问题,因此另一种方法是“创建目录,然后检查结果以查看它是失败(不好)还是在目录上(好的)。也是检查故障,并引用以防止 POSIX split 和 glob 事件。-d
mkdir
EEXIST
cd
$TARGET