【问题标题】:sh script: no output when run in mounted filesystemsh 脚本:在挂载的文件系统中运行时没有输出
【发布时间】:2013-06-29 19:40:24
【问题描述】:

需要一些帮助才能了解问题所在。 简而言之:我编写了一个 bourne shell 脚本,它在目标目录中创建指向源目录内容的链接。 它在主机系统上运行良好,但是当针对挂载 fs 上的目录(来自 chroot 和本机系统)时,它不起作用并且根本不提供任何输出。

详情: 挂载 fs: ext3, rw

主机系统:3.2.0-48-generic #74-Ubuntu SMP GNU/Linux

为了缩小问题范围,以“/usr”为例。

主机系统中“/usr”的权限:drwxr-xr-x

挂载分区上“/usr”的权限:drwxr-xr-x

尝试从主机系统同时使用 bash 和 dash。相同的结果 - 适用于本机文件系统,不适用于挂载。

脚本(cord.sh;在我的情况下从根目录运行):

# !/bin/sh

SRCFOLDER=$2                    # folder with package installation
DESTFOLDER=$3                   # destination folder to install symlinks to ('/' - for base sys; '/usr' - userland)
TARGETS=$(ls $SRCFOLDER)        # targets to handle

SRCFOLDER=${SRCFOLDER%/}        # stripping slashes from the end, if they are present
DESTFOLDER=${DESTFOLDER%/}      #

##
## LINKING
##

if [ "$1" = "-c" ];
    then printf %s "$TARGETS" | while IFS= read -r line
        do
            current_target=$(file $SRCFOLDER/$line)     # had an issue with different output in different systems
            if [ "${current_target% }" = "$SRCFOLDER/$line: directory" ];   # stripping space helped
                then
                    mkdir -v $DESTFOLDER/$line    # if other package created it - it'll fail
                    /usr/local/bin/cord.sh -c $SRCFOLDER/$line $DESTFOLDER/$line                   # RECURSION
            else
                ln -sv $SRCFOLDER/$line $DESTFOLDER/$line   # will fail, if exists
            fi;
        done

##
## REMOVING LINKS
##

elif [ "$1" = "-d" ];
    then printf %s "$TARGETS" | while IFS= read -r line
        do
            current_target=$(file $SRCFOLDER/$line)
            if [ "${current_target% }" = "$SRCFOLDER/$line: directory" ];
                then
                    /usr/local/bin/cord.sh -d $SRCFOLDER/$line $DESTFOLDER/$line                   # RECURSION
            else
                rm -v $DESTFOLDER/$line
            fi;
        done


elif [ "$1" = "-h" ];
    then
        echo "Usage:"
        echo "cord -c /path/to/pkgdir /path/to/linkdir  -   create simlinks for package contents"
        echo "cord -d /path/to/pkgdir /path/to/linkdir  -   delete links for package"
        echo "cord -h                                   -   displays this help note"


else
    echo "Usage:"
    echo "cord -c /path/to/pkgdir /path/to/linkdir  -   create simlinks for package contents"
    echo "cord -d /path/to/pkgdir /path/to/linkdir  -   delete links for package"
    echo "cord -h                                   -   displays this help note"

fi;

最明显的建议是权限问题。然而一切看起来都很正常。也许我错过了什么?

【问题讨论】:

    标签: unix permissions sh


    【解决方案1】:

    我不知道您的主要问题可能是什么(权限或其他问题 - 您应该包含一个示例,说明您如何运行脚本以及如何使用安装程序和所有内容为它做准备)。但是这个脚本是可以清理的。

    首先,如果要测试某个东西是否是目录,请使用

    if [ -d "$something ]
    

    这将摆脱笨拙的file 用法。

    其次,不要执行将$TARGETS 数组转换为一系列行然后循环读取这些行的冗余步骤。直接遍历数组即可。

    for line in $TARGETS
    

    另外,我不会使用ls 来填充文件名数组,而是使用glob。但不是其中任何一个,我会使用find,因此它可以处理递归并通过调用同一脚本进行递归来消除您正在创建的进程树。而不是编写符号链接树生成器脚本,我会使用类似 lndir 的东西,它已经为此目的存在......

    【讨论】:

    • 呃……现在我感到很惭愧。并不是要发明另一辆自行车。我只是在基本系统中没有lndir 并且不知道它。谢谢。
    • 哦!有什么东西可以删除创建的链接吗?例如,/usr/packages/foo 链接到 /usr 的内容。需要一些东西来删除仅包foo的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多