退出脚本中的 bash 命令而不退出脚本

退出脚本中的 bash 命令而不退出脚本

我正在编写一个脚本,该脚本会查看作业文件夹(源文件),如果该文件夹存在,则查找目标文件夹。如果该文件夹不存在,则将源复制到目标。

如果目标存在,它会尝试将文件从源复制到目标,并且在执行此操作之前先提示用户,以免覆盖该用户已经完成的工作。

命令的输出必须采用特定格式,因此我无法按原样使用命令的标准输出。我必须捕获它并重新格式化。然后以特定格式输入(即 y/N)。

这样做的好处是,复制命令已经做了一些有用的事情。如果文件不存在,它会进行复制。

如果一个或多个文件已经存在,它会反复询问“是否覆盖?”我正在尝试处理这种情况。

我已经将复制命令的输出捕获到变量中并抑制其正常输出,以便我可以重新格式化其输出并将该格式回显给用户。

接下来,我的想法是我需要终止(或以其他方式停止命令),然后以我想要的格式打印输出,然后重新调用命令,第二次,我可以以我想要的格式回显 y/N 提示,然后用户可以做出选择。尽管搜索过,但我还是无法弄清楚/理解如何在调用命令后终止或以其他方式停止命令。我试过 kill 和使用 SIGINT 的各种尝试。要么我只是不明白如何使用它们,要么它们不是正确的选择。当我尝试使用它们时,我得到了语法错误。

这是我的代码:

#!/bin/bash

USAGE="Usage: ./script2.sh [hw-name]"
EINVALID="Invalid homework: $1"
SOURCEDIRECTORY="$PUBLIC/homework/$1"
HOMEWORKDIRECTORY="$HOME/homework/$1"
COPY="$SOURCEDIRECTORY/*.*"

if [ -z "$1" ]; then
    echo $USAGE
    exit
fi

if [ ! -d "$SOURCEDIRECTORY" ]; then
    echo $EINVALID
    exit
fi

if [ ! -d "$HOMEWORKDIRECTORY" ]; then
    echo "making homework1"
    mkdir -p $HOMEWORKDIRECTORY

copyOutput2="$(eval cp -ir $COPY $HOMEWORKDIRECTORY 2>&1 &stop this
 process somehow)"
echo $copyOutput2 #temporary output for testing

答案1

如果确实需要自定义cp消息,那么从源代码重新编译程序是可行的方法,但更明智的方法是通过printf最好地写出自己的消息,而不是试图拦截的cp输出,并通过select对话框处理用户选择。此外,如果您要输出错误消息,它们应该进入stderr流。最后,*.*是不必要的,您可以改用*glob。

以下是经过几处编辑的脚本。请注意,您需要取消注释#cp "$item" "$HOMEWORKDIRECTORY"行才能进行实际复制。出于测试目的,请先将其替换cpecho

#!/bin/bash

USAGE="Usage: ./script2.sh [hw-name]"
EINVALID="Invalid homework: $1"
SOURCEDIRECTORY="$PUBLIC/homework/$1"
HOMEWORKDIRECTORY="$HOME/homework/$1"
#COPY="$SOURCEDIRECTORY/*.*"

if [ -z "$1" ]; then
    echo "$USAGE" > /dev/stderr
    exit 1
fi

if [ ! -d "$SOURCEDIRECTORY" ]; then
    echo "$EINVALID" > /dev/stderr
    exit 2
fi

if [ ! -d "$HOMEWORKDIRECTORY" ]; then
    echo "making homework1"
    mkdir -p $HOMEWORKDIRECTORY

for item in "$SOURCEDIRECTORY"/*; do
    skip=true
    if [ -f "$HOMEWORKDIRECTORY"/"${item##*/}" ]; then
        printf "%s already exists in %s.\n" "$item" "$HOMEWORKDIRECTORY"

        select choice in  "overwrite" "skip"; do
            case "$choice" in 
                "overwrite")  echo "Overwriting."  
                              break;;
                "skip") skip=true; break;;
            esac
        done
    fi

    if [ "$skip" = "true" ]; then
        continue
    fi
    echo cp "$item" "$HOMEWORKDIRECTORY"

done

相关内容