Shell Scripts - (don't run properly) - What am I missing?

I have a shell script that looks for new lets-encrypt certs pushed from my server that does LE for the rest of the network and copies from pem_filename.new to just the .pem filenames they need to be in /ssl.

If I run the script from the SSH add-on from a prompt manually, that works.

but I’ve tried adding the shell_command to both configuration.yaml and a shell_commands.yaml file in /config.

shell_command:
  check_update_ssl: /bin/bash /config/shell/update_ssl.sh

(both with and without ‘bash’ or ‘/bin/bash’, etc…)

And the automation tab entry lists the shell_command for me. So I can set something up there. But when I manually run it - nothing seems to happen.

I’m running the latest Home Assistant in a VM via Virtualbox using the .VDI starter image.

Is there something else I’m missing?

Thanks a bunch,

-Ben

When you say “run in manually”, are you going into the Actions (or Service Calls) tab of Developer Tools? If so, when You click on “Perform Action” (or whatever it was in older updates), does the button turn green with a tick? And then you’re getting no Response result? Maybe look in the logs?

Please post the code of that

How about file permissions ?

You say the script works, So next easy thing would be permissions, after that it would be the logfile from HA to see whats wrong…

You shouldn’t have to call /bin/bash first, you should have that already in the first line of your script:

#!/bin/bash

But even that isn’t totally needed in most cases today, but it covers all your bases just in case. If you did that then your shell command could simply be:

check_update_ssl: "/config/shell/update_ssl.sh"

Sorry for the delayed reply - I thought I had email notifications enabled… Here ya go – there isn’t much to it.

Basically - the sign it ran is the files “.new” should be gone. Nothing happens.

If I run it from the ssh add-on from a local shell (in the web gui) - the script works.

#!/bin/bash

SSLKEY="/ssl/privkey.pem"
SSLCERT="/ssl/fullchain.pem"


if [[ -e "$SSLKEY.new" && -e "$SSLCERT.new" ]]; then
	echo "New keys found. Copying into place."

	mv -f $SSLCERT.new $SSLCERT
	mv -f $SSLKEY.new  $SSLKEY

fi

exit 0

Thanks!

-Ben

Sorry for the delay - I thought I had notifications on.

Tried with and without the /bin/bash in the yaml line. I’ll try again without.

I tried to follow Shell Command - Home Assistant but it’s kind of a hot mess. The examples there list “bash” in the YAML config line. But looking around online, some people leave it out. I was trying everything.

I’m also used to writing shell scripts calling which shell I want with the 1st line of the script.

Just tried it - that line as listed doesn’t work.

The script was originally set to rwxr–r–, I made it 755 just now (rwxr-x-r-x) and that didn’t fix things.

the script is owned by root/root
the files in /ssl/ are also owned by root/root

So the question is: Who runs this? when I look in /etc/passwd, I see several contenders.

root?
operator?
guest?
nobody?

The docs (last I looked) didn’t discuss anything about who was running the script to make sure file perms on the script were correct or SUID had to be set somehow.

I was running it from the automations page both under automations for the one I made running at a certain time.

but I also tried running it from the scripts page.

with your suggestion, I ran it from the developer->actions page and get a green check-mark. Nothing happens. (should anything I throw to stdout be shown as a response? because the script has some output - but I don’t see it in the response field)

Thanks,

-Ben

Ohhhhhh… I see the problem.

When I enable “debug” for the shell_command integration, run my script (via dev tools->actions) and then turn off and the log downloads, I see this:

2024-11-02 12:40:18.894 DEBUG (MainThread) [homeassistant.components.shell_command] Stderr of command: `/config/shell/update_ssl.sh`, return code: 0:
b"touch: /ssl/running.txt: Read-only file system\nmv: can't rename '/ssl/fullchain.pem.new': Read-only file system\nmv: can't rename '/ssl/privkey.pem.new': Read-only file system\n"

When I jump into the ‘ssh shell’ add-on and do a “mount” – I see:

/dev/sda8 on /ssl type ext4 (rw, relatime,commit=30)

And ‘ls -l /’ shows /ssl being rwxr-xr-x.

But if I run the script via ssh/shell add-on, it works. (where the user running the script is root)

What’s the best way to fix this?

Hi @bkamen,

That script should work indeed. Would write it differently but ahwel :slight_smile:

the script is owned by root/root
the files in /ssl/ are also owned by root/root

With:

rwxr-x-r-x

So that should allow any user om the system to at least execute the script. Good start .

The answer is simple :slight_smile:

Your system complains that it cannot write to the /ssl directory and with 755 that sure is the case. You would need to make it writable too. Ideally 775 But as you dont know the user and what group it belongs to you can do this:

#make directory 777
chmod -R 777 /ssl
# Add this to your script: 
echo $(whoami) >> /ssl/user
# read the file and try to figure out what group that user belongs to: 
cat /ssl/user | id
# You can now make the folder group owned: 
chown -R root:GROUPNAMEHERE /ssl
# Reduce rights: 
chmod -R 775 /ssl

Hope that helps :slight_smile:

Eeek. I’ll see what works.

like - I know how to mount/unmount and SUID stuff – but docker containers are new so I have no idea how all this is shelled and such.

Let me see what I can figure out. chmod 777… ugh. :stuck_out_tongue:

Nope. That didn’t work. It’s not “permission denied” – it’s “Read-only file system”.

So within the context of this whole docker system, not sure how to fix that.

Trying to write “whoami” into a file fails for the same reason.

Any other thoughts? (open question to anyone)

-Ben

You have to fully understand 2 notions:

  1. the addons environment is basically totally different than the actual HA environment: both runs in 2 different docker container; that “/ssl” exists in the SSH addon doesn’t mean it exists in HA (and actually it doesn’t), and that a binary exists in an addon doesn’t mean it exists in HA

  2. The only directory that is the same in both environment is “/config”

Bottom-line: only work with “/config/*”

OoooOoOooohhhhh… very useful info. Thank you.

So it sounds like I should change my configuration.yaml to point to my certs in (say) /config/certs (or something) and then have my script operate out of there.

Let me try that.

-Ben

That was it!

So now -

  • configuration.yaml points to certs in /config/ssl/
  • my letsencrypt server now mounts/deploys new SSL certs to //hass/config/ssl

At some point, I need to make the script run on a time/date after I know the letsencrypt happens.

But then when the script DOES run, it properly sees the new certs and then copies them into place.

I’ll add a completion-code check next which causes HASS to restart (thus loading the new certs)

Fabulous - thanks!

-Ben