Выйти из команды bash в сценарии, не выходя из сценария

Я работаю над сценарием, который просматривает домашнюю папку (исходные файлы), и если папка существует, она ищет целевую папку. Если эта папка не существует, она копирует источник в место назначения.

Если место назначения существует, оно пытается скопировать файл из источника в место назначения и, прежде чем сделать это, сначала попросит пользователя не перезаписывать работу, уже проделанную этим пользователем.

Вывод команды должен быть в определенном формате, поэтому я не могу использовать стандартный вывод команды как есть. Я должен захватить это и переформатировать это. Затем возьмите ввод (т.е. y/N) в определенном формате.

Преимущество этого состоит в том, что команда copy уже делает полезные вещи. Если файл не существует, он делает копию.

Если файл или несколько файлов уже существуют, он будет постоянно спрашивать "перезаписать y/n?" Это тот случай, с которым я пытаюсь разобраться.

Я сделал это так, чтобы захватить вывод команды copy в переменную и подавить ее нормальный вывод, чтобы я мог переформатировать ее вывод и передать этот формат пользователю.

Далее я думаю, что мне нужно убить (или как-то иначе остановить команду), затем распечатать вывод в желаемом формате, а затем повторно вызвать команду, и во второй раз я могу повторить запрос y / N в мой желаемый формат, и пользователь может сделать свой выбор. Несмотря на поиск, я не смог выяснить / понять, как убить или иным образом остановить команду после ее вызова. Я пытался убить и различные попытки использования 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 поток. В заключение, *.* не нужно, и вы можете просто использовать * вместо этого

Ниже приведен скрипт с парой правок. Обратите внимание, что вам нужно раскомментировать #cp "$item" "$HOMEWORKDIRECTORY" строка для фактического копирования. В целях тестирования замените cp с echo первый.

#!/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
Другие вопросы по тегам