1

So I made a bash script to ssh onto lots of computers and play a sound all at once. I'm running into issues when trying to sync them though. My approach is:

Get current epoch on my computer,
Add a 20 second delay (to allow for transfer times) [target_epoch]
connect to & send .wav files to each computer in parallel. 
Run a few lines of bash on each computer:
    sync time with google, 
    get bot epoch
    calc how long to sleep based off: target_epoch - bot_epoch
    sleep and then play .wav file

Getting my computer epoch with:

current_epoch=$(date +%s.%N)
target_epoch=$(echo "$current_epoch + 20"|bc) 

Code running on each remote computer:

sudo date -s '$(wget --method=HEAD -qSO- --max-redirect=0 google.com 2>&1 | sed -n 's/^ *Date: *//p')';\
bot_current_epoch=$(date +%s.%N);\
echo 'Current epoch: ' ${bot_current_epoch};\
echo 'Target epoch:  ' ${target_epoch};\
amixer set 'Master' ${volume}% 1> /dev/null;\
echo 'Sleep until:${target_epoch} time now:  ${bot_current_epoch}' ;\
echo 'Sleep for: '$(echo "$target_epoch - $bot_current_epoch"|bc);\
sleep $(echo "$target_epoch - $bot_current_epoch"|bc);\
aplay /tmp/${wavFile} 2> /dev/null;"

(oh, I'm saving that code as a string and then passing it via ssh to the remote computer)

the issue I have is that it's not setting the bot_current_epoch variable

originally I had bot_current_epoch use the same name as current_epoch and so it didn't update the current epoch time so all bots just waited for the 20-second delay and didn't actually sync up. When I changed the var to bot_current_epoch it failled and I noticed that bot_current_epoch=$(date +%s.%N);\ wasn't actually updating the var

11
  • 1
    So you would transfer all the files in parallel, then wait Why not use parallel or xargs (or ansible) to manage background processes for you? I would rather consider bash scripting on the end. An issue with that would be that you are reestablishing Use ControlMaster in ssh settings to reuse connection. There are odd \ on the end of each line in your script. It's not like no one has done it before you, the general solution is ansible, puppet or other configuration management tool. Commented Nov 21, 2023 at 19:44
  • 1
    You are specifying the requirements. You want them synchronized (ansible execution strategy "linear") or all run in parallel ("free" execution strategy in ansible)? How do you "sync files"? Why in your script do you pass date -s with a single quoted argument? And why use date -s at all, and not timesyncd or ntpd? I run away. Commented Nov 21, 2023 at 19:49
  • 1
    Your last command block sudo date -s '$(wget ... has syntax errors. You can already see on the syntax highlighting here, that the ' is closed at sed -n '. But even if it wasn't, having $() inside a single quoted string at that place seems suspicious. Try to fix those syntax errors. shellcheck.net can help you with that and even more. Commented Nov 21, 2023 at 21:27
  • 1
    Escaping code to run on a remote server is something you should have the shell do for you -- doing it by hand is very error-prone even for experts. The easy way is to write a shell function with the code you want to remotely run; after you do that, "$(declare -f the_function_name); the_function_name" evaluates to a string that runs that code inside the function named, ready to pass to ssh. (If you need to pass variables over ssh, use declare -p to serialize them the same way). Commented Nov 21, 2023 at 21:27
  • 1
    saving that code as a string and then passing it via ssh to the remote computer : Not a good idea. Too error prone. To rule out the possibility that stringification causes trouble, store the code as a script which is accessible on the remote system and execute this script. Commented Nov 22, 2023 at 8:11

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.