Я работаю над скриптом, который просматривает папку с домашним заданием (исходные файлы) и, если папка существует, ищет папку назначения. Если эта папка не существует, он копирует исходный файл в папку назначения.
Если место назначения существует, программа пытается скопировать файл из источника в место назначения, но перед этим запрашивает у пользователя подтверждение, чтобы не перезаписывать работу, уже выполненную этим пользователем.
Вывод команды должен быть в определенном формате, поэтому я не могу использовать стандартный вывод команды как есть. Я должен захватить его и переформатировать. Затем взять ввод (т. е. y/N) в определенном формате.
Преимущество этого в том, что команда копирования уже делает полезные вещи. Если файл не существует, она делает копию.
Если файл или несколько файлов уже существуют, система будет неоднократно спрашивать: «Перезаписать 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
Если вам действительно очень-очень нужно иметь custom cp
с custom message, то перекомпиляция программы из исходников — это выход, но немного более разумным подходом было бы написать собственное сообщение через printf
preferred, вместо того, чтобы пытаться перехватить cp
вывод , и обрабатывать выбор пользователя через select
dialog. Кроме того, если вы собираетесь выводить сообщения об ошибках, они должны идти в stderr
stream. Наконец, *.*
не нужно, и вы можете просто использовать *
glob вместо этого.
Ниже приведен скрипт с парой правок. Обратите внимание, что вам нужно раскомментировать #cp "$item" "$HOMEWORKDIRECTORY"
строку, чтобы произошло фактическое копирование. Для целей тестирования замените cp
на echo
first.
#!/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