0

I want copy some files, but I want to wait executing the copy commands untill the end of the script. The reason for this is I can expect a user input to interrupt the script halfway, and I don't won't a partially copied directory.

Is there any way I can wait to execute specific commands until exit 0 is seen in the same program?

#!/bin/bash
for f in 'find something/ -newer something_else -type f'; do
   #Expecting user input interruption
   cp "$f" . #I want to wait executing this
done

if [ -f something_else ]; then
   exit 0 #I want it executed here
else 
   exit 1
fi
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Martin
  • 35
  • 1
  • 6
  • 2
    Can control flow through the script be changed so that copying happens after `exit 1` is potentially executed? Also, don't loop over the result of `find`, and remember to double-quote your variable expansions. – Kusalananda Mar 03 '18 at 12:11
  • I want the copy commands to be determined inside the loop, but be executed later, because I take user input to determine the exit status during the loop. – Martin Mar 03 '18 at 12:17
  • That is not reflected in the script that you showed us. – Kusalananda Mar 03 '18 at 12:18
  • Why not loop through the results of find? – Martin Mar 03 '18 at 12:18
  • 1
    See the question [Why is looping over find's output bad practice?](https://unix.stackexchange.com/questions/321697/why-is-looping-over-finds-output-bad-practice) – Kusalananda Mar 03 '18 at 12:19

1 Answers1

0

The easiest solution would be to do the copying later:

#!/bin/bash

# something something script stuff

[ ! -f somefile ] && exit 1

find something -type f -newer somefile -exec cp {} . ';'

If you want the user to confirm each copy, use -ok instead of -exec in find:

find something -type f -newer somefile -ok cp {} . ';'

To first loop over the file to create a list of files to copy, asking the user for input for each file, and then perform the copy:

copy_these=$(mktemp)

find something -type newer somefile \
    -exec bash -c '
        read -p "Copy $0? [y/n/q]: "
        case "$REPLY" in
            [yY]*) printf "%s\n" "$0" ;;
            [qQ]*) exit 1 ;;
        esac' {} ';' >"$copy_these"

# do other stuff

# then copy the files

xargs cp -t . <"$copy_these"

rm -f "$copy_these"

Note that this assumes that all filenames are well behaved (no newlines), and that GNU cp is used.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936