奇点不合逻辑 "Bad substitution"
Illogical "Bad substitution" in singularity
问题
我的奇点容器中的一个包中的一个配置脚本包含这个完全合理的(对我来说)bash 位到 trim 路径的尾随 /
;
if [ "${MY_DIR_PATH: -1}" = "/" ]; then
MY_DIR_PATH="${MY_DIR_PATH%?}"
fi
它在我的机器上本机运行良好,但是当来自奇点容器的 %post
部分的 运行 时,它失败并显示 Bad substitution
。
出了什么问题,正确的解决方法是什么?
最小工作示例
将下面的文本保存为badSubs.def
然后尝试; sudo singularity build badSubs.sif badSubs.def
.
BootStrap: docker
From: ubuntu:18.04
# what is done when the container is built
%post
# make print colour #
GREEN='3[0;32m'
NOCOLOUR='3[0m'
# start
#echo "${GREEN}~~~ Give the user permission and control ~~~ ${NOCOLOUR}"
#umask 000
echo "${GREEN}~~~ this should work fine! ~~~ ${NOCOLOUR}"
MYSCRIPT=$SINGULAITY_ROOTFS/confuzzel
touch $MYSCRIPT
chmod u+x $MYSCRIPT
echo '#! /bin/bash' >> $MYSCRIPT
echo 'PATHY="/what/a/path/"' >> $MYSCRIPT
echo 'if [ "${PATHY: -1}" = "/" ]; then ' >> $MYSCRIPT
echo ' echo yay!' >> $MYSCRIPT
echo ' PATHY="${PATHY%?}"' >> $MYSCRIPT
echo 'fi' >> $MYSCRIPT
echo 'echo $PATHY' >> $MYSCRIPT
cat $MYSCRIPT
./confuzzel
# metadata
%labels
Author ClumsyCat
Version v1.0
%help
to build me
> sudo singularity build badSubs.sif badSubs.def
to run me do
> singularity run badSubs.sif
好的,回答我自己的问题,因为我找到了一些有用的东西;
if [ $(echo -n $MY_DIR_PATH | tail -c 1) = "/" ]; then
MY_DIR_PATH="${MY_DIR_PATH%?}"
fi
灵感来自
如果有人想 answer/add 以解释为什么有效的方式回答这个答案,我会接受这个答案。
我对奇点不熟悉,所以这是一个猜测,但我认为你的脚本被 shell bash 以外的 运行 (可能是破折号?) . ${var: number}
是变量扩展语法的非标准扩展; bash 和其他一些 shell 支持它,其他人(如 dash)不支持。
如果测试的唯一原因是查明变量是否以“/”结尾以便您可以删除它(如果它在那里),请不要费心。这是 POSIX-standard 语法,它将从变量的末尾删除“/” if 变量以“/”结尾:
MY_DIR_PATH=${MY_DIR_PATH%/}
如果您确实需要测试,请改用它:
if [ "${MY_DIR_PATH%/}" != "${MY_DIR_PATH}" ]; then
说明:这里比较的是把末尾去掉“/”的变量和原来的值进行比较;如果它们不同,那么末尾一定有一个“/”。
问题
我的奇点容器中的一个包中的一个配置脚本包含这个完全合理的(对我来说)bash 位到 trim 路径的尾随 /
;
if [ "${MY_DIR_PATH: -1}" = "/" ]; then
MY_DIR_PATH="${MY_DIR_PATH%?}"
fi
它在我的机器上本机运行良好,但是当来自奇点容器的 %post
部分的 运行 时,它失败并显示 Bad substitution
。
出了什么问题,正确的解决方法是什么?
最小工作示例
将下面的文本保存为badSubs.def
然后尝试; sudo singularity build badSubs.sif badSubs.def
.
BootStrap: docker
From: ubuntu:18.04
# what is done when the container is built
%post
# make print colour #
GREEN='3[0;32m'
NOCOLOUR='3[0m'
# start
#echo "${GREEN}~~~ Give the user permission and control ~~~ ${NOCOLOUR}"
#umask 000
echo "${GREEN}~~~ this should work fine! ~~~ ${NOCOLOUR}"
MYSCRIPT=$SINGULAITY_ROOTFS/confuzzel
touch $MYSCRIPT
chmod u+x $MYSCRIPT
echo '#! /bin/bash' >> $MYSCRIPT
echo 'PATHY="/what/a/path/"' >> $MYSCRIPT
echo 'if [ "${PATHY: -1}" = "/" ]; then ' >> $MYSCRIPT
echo ' echo yay!' >> $MYSCRIPT
echo ' PATHY="${PATHY%?}"' >> $MYSCRIPT
echo 'fi' >> $MYSCRIPT
echo 'echo $PATHY' >> $MYSCRIPT
cat $MYSCRIPT
./confuzzel
# metadata
%labels
Author ClumsyCat
Version v1.0
%help
to build me
> sudo singularity build badSubs.sif badSubs.def
to run me do
> singularity run badSubs.sif
好的,回答我自己的问题,因为我找到了一些有用的东西;
if [ $(echo -n $MY_DIR_PATH | tail -c 1) = "/" ]; then
MY_DIR_PATH="${MY_DIR_PATH%?}"
fi
灵感来自
如果有人想 answer/add 以解释为什么有效的方式回答这个答案,我会接受这个答案。
我对奇点不熟悉,所以这是一个猜测,但我认为你的脚本被 shell bash 以外的 运行 (可能是破折号?) . ${var: number}
是变量扩展语法的非标准扩展; bash 和其他一些 shell 支持它,其他人(如 dash)不支持。
如果测试的唯一原因是查明变量是否以“/”结尾以便您可以删除它(如果它在那里),请不要费心。这是 POSIX-standard 语法,它将从变量的末尾删除“/” if 变量以“/”结尾:
MY_DIR_PATH=${MY_DIR_PATH%/}
如果您确实需要测试,请改用它:
if [ "${MY_DIR_PATH%/}" != "${MY_DIR_PATH}" ]; then
说明:这里比较的是把末尾去掉“/”的变量和原来的值进行比较;如果它们不同,那么末尾一定有一个“/”。