I have a bash script that, among other things, runs a command. For context, it's running a unison profile for file synchronisation.
The script takes parameters which are passed to the unison function, like so (shortened)
#!/bin/bash
unisonparameters=$1
unisonresult=$( { unison $unisonparameters local; } )
if [ $? -ne 0 ]
then
<<send email using $unisonresult>>
fi
I'd like to be able, to run the script in 2 ways:
as a cronjob, in which case I pass the parameters that require no user interaction (
-batch), and the scripts emails me in case there is an issue.as a user-initiated action, in which case I pass no parameters, so that
unisonasks me what I want to do with the files it found. In this case I'm indifferent to whether or not an email is sent.
I was hoping the script above would work, but as discussed in the comments it does not. Is there a way to make it work?
Additional information 1
I've been trying to get the script to ask for user input if I pass no parameters (so that $unisonparameters = ''). Here are the results
Working
If dont try to save the output to a variable, like so:
unison $unisonparameters local
if [ $? -ne 0 ]
then
<<send email>>
fi
, all is run as expected and without error:
elrudi@dell:~$ ./syncnas.sh
Mon Oct 22 22:23:17 CEST 2018
Syncing data with nas.
Found a local device at 192.168.1.100 to connect to.
running command 'unison local'...
Contacting server...
Connected [//nas//share/HDA_DATA/elrudi -> //dell//home/elrudi]
Looking for changes
Waiting for changes from server
Reconciling changes
local nas
new dir ----> syncAll/newFolder
new file ---->
(...)
(first lines due to other parts in script.)
Broken
However, if I use the original line in the script above, trying to store the output of this command:
unisonresult=$( { unison $unisonparameters local; } )
if [ $? -ne 0 ]
then
<<send email>>
fi
, it hangs on the unison command:
elrudi@dell:~$ ./syncnas.sh
Mon Oct 22 22:01:17 CEST 2018
Syncing data with nas.
Found a local device at 192.168.1.100 to connect to.
running command 'unison local'...
Contacting server...
Connected [//nas//share/HDA_DATA/elrudi -> //dell//home/elrudi]
Looking for changes
Waiting for changes from server
Reconciling changes
Terminated!
(Last line caused by my eventual ctrl-c.)
Additional information 2
I've tried adding -debug verbose to the unison command to get some more information. In both cases the output is very long. The interesting part is at the end, which i'm showing below.
Working
In the first case, with unison $unisonparameters -debug verbose local the script eventually asks for user input regarding which files to sync in which direction:
(...)
[server: update+] Archive name is //nas//share/HDA_DATA/elrudi;//nas//share/HDA_DATA/elrudi, //xps//home/elrudi;22; hashcode is 1cee08d0fa648cd9d77332dc9623b39e
[server: remote+] Sending result (id: 16)
[server: remote+] send [unlockArchive-res] '\132\149\166\190\000\000\000\001\000\000...' 21 bytes
[server: remote+] send [rsp] '\132\149\166\190\000\000\000\001\000\000...' 21 bytes
[server: remote_emit+] dump: \016\000\000\000\246\024\000\000\000\233rsp\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@&\000\000\000\018unlockArchive-res\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@
[remote_emit+] grab: \016\000\000\000\246\024\000\000\000\233rsp\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@&\000\000\000\018unlockArchive-res\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@
[remote+] Message received (id: 16)
[remote+] receive 'rsp\132\149\166\190\000\000\000...' 24 bytes
[remote+] receive 'unlockArch...' 38 bytes
[remote+] Waiting for next message
(...)
[pred] preferpartial 'syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg' = false
[pred] forcepartial 'syncFolder/Software_Config/Qnap/3_Unison/syncnas.sh' = false
[pred] preferpartial 'syncFolder/Software_Config/Qnap/3_Unison/syncnas.sh' = false
[pred] forcepartial 'syncFolder/test2.txt' = false
[pred] preferpartial 'syncFolder/test2.txt' = false
[pred] forcepartial 'syncFolder/test4txt' = false
[pred] preferpartial 'syncFolder/test4txt' = false
local nas
new file ----> syncFolder/Software_Config/Linux/variety/Downloaded/Desktoppr/02126_snowytracks_2560x1600.jpg
new file ----> syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg
changed ----> syncFolder/Software_Config/Qnap/3_Unison/syncnas.sh
new file ----> syncFolder/test2.txt
new file ----> syncFolder/test4txt
Proceed with propagating updates? []
Broken
In the second case, with unisonresult=$( { unison $unisonparameters -debug verbose local; } ) the script (i.e., the unison command) does not show the prompt:
(...)
[server: update+] Unchanged file
[server: fileinfo+] /share/HDA_DATA/elrudi/syncFolder: true 1540240561.000000 1540240561.000000
[server: update] Setting archive for //nas//share/HDA_DATA/elrudi
[server: remote+] Sending result (id: 9)
[server: remote+] send [find-res] '\132\149\166\190\000\000\000/\000\000...' 67 bytes
[server: remote+] send [rsp] '\132\149\166\190\000\000\000\001\000\000...' 21 bytes
[remote_emit+] grab: \t\000\000\000b\024\000\000\000\233rsp\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@K\000\000\000\181find-res\132\149\166\190\000\000\000/\000\000\000\000\000\000\000 \000\000\000\029\160\176'syncFolder@\160\224\160\001\001\255\001\003\255@@\145\012\000\000\128 \223\214A@\018_j\000\000\000\000\000\000\000\000\000@@
[remote+] Message received (id: 9)
[server: remote_emit+] dump: \t\000\000\000b\024\000\000\000\233rsp\132\149\166\190\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000@K\000\000\000\181find-res\132\149\166\190\000\000\000/\000\000\000\000\000\000\000 \000\000\000\029\160\176'syncFolder@\160\224\160\001\001\255\001\003\255@@\145\012\000\000\128 \223\214A@\018_j\000\000\000\000\000\000\000\000\000@@
[remote+] receive 'rsp\132\149\166\190\000\000\000...' 24 bytes
[remote+] receive 'find-res\132\149...' 75 bytes
[remote+] Waiting for next message
Reconciling changes
[recon] reconcileAll
[recon] reconcile: 3 results
[update] Marking 0 paths equal
[pred] sortlast 'syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg' = false
[pred] sortlast 'syncFolder/test.txt' = false
[pred] sortfirst 'syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg' = false
[pred] sortfirst 'syncFolder/test.txt' = false
[sort] syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg <= syncFolder/test.txt --> -1
[pred] sortlast 'syncFolder/test.txt' = false
[pred] sortlast 'syncFolder/test2.txt' = false
[pred] sortfirst 'syncFolder/test.txt' = false
[pred] sortfirst 'syncFolder/test2.txt' = false
[sort] syncFolder/test.txt <= syncFolder/test2.txt --> -1
[pred] forcepartial 'syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg' = false
[pred] preferpartial 'syncFolder/Software_Config/Linux/variety/Downloaded/Unsplash/photo-1535941863447-76a4dc94e2ba.jpg' = false
[pred] forcepartial 'syncFolder/test.txt' = false
[pred] preferpartial 'syncFolder/test.txt' = false
[pred] forcepartial 'syncFolder/test2.txt' = false
[pred] preferpartial 'syncFolder/test2.txt' = false
(hangs on last line)
Hope that helps!
unisonresult=$( unison local )should be sufficient; the command group is unnecessary.unison local > /tmp/unison$$.out 2>&1to capture both stdout and stderr to the file. Then use that file, and remove it... But I don't know why your solution is hanging... :-(whileloop insyncnas.shthat looks at a variable set byunison? Whenunisonruns in a subshell, variables set byunisonae lost after terminating that shell.{ unison local > /dev/fd/3 2>&1; x=$(cat<&3); } 3<<< ''; echo "${x}". The drawback of this solution is that you only see the output ofunisonwhen the command is finished. When this resolves thehangingproblem, the solution might be usingteeas in stackoverflow.com/a/42636741/3220113unisonis trying to interact with your TTY, well, there you are. Redirecting stdin</dev/nullis a good way to stop that from happening, if "stopping that from happening" is appropriate.