0

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:

  1. 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.

  2. as a user-initiated action, in which case I pass no parameters, so that unison asks 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!

6
  • 1
    I doubt this should matter, but unisonresult=$( unison local ) should be sufficient; the command group is unnecessary. Commented Oct 22, 2018 at 21:07
  • I would have tried unison local > /tmp/unison$$.out 2>&1 to 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... :-( Commented Oct 22, 2018 at 21:27
  • Do you have a while loop in syncnas.sh that looks at a variable set by unison? When unison runs in a subshell, variables set by unison ae lost after terminating that shell. Commented Oct 23, 2018 at 10:08
  • Inspired by unix.stackexchange.com/a/365228/57293, you can try { 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 of unison when the command is finished. When this resolves the hanging problem, the solution might be using tee as in stackoverflow.com/a/42636741/3220113 Commented Oct 23, 2018 at 10:30
  • If unison is trying to interact with your TTY, well, there you are. Redirecting stdin </dev/null is a good way to stop that from happening, if "stopping that from happening" is appropriate. Commented Oct 24, 2018 at 21:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.