0

I'm trying to create a bash script to perform some maintenance tasks on a remote server using ssh. I've been trying to figure it out on my own, but I'm having some difficulty. I was hoping someone here on Stack Overflow might be able to help me out.

I'm not very familiar with bash scripting, so any guidance or suggestions you could provide would be greatly appreciated.

Here's what I'm trying to accomplish:

  1. Connect to a remote server via ssh
  2. Delete files that are older than 3 months
  3. Update server packages
  4. Check disk sizes and send a notification if the disk is 75% full

Commands:

  1. SSH into the remote server.
  2. Update server packages.
  3. Delete files older than 3 months.
  4. Check disk sizes and send notification if 75% full.
# maintenance.sh
# Connect to the remote server
ssh username@remote_server_ip "cd /"

# Update server packages
ssh username@server "apt-get update && apt-get upgrade"

# Delete files older than 3 months
ssh username@server "find home/ -mtime +90 -delete"

# Check disk sizes and send notification if 75% full
ssh username@server "disk_size=$(df -h / | grep -v Filesystem | awk '{print $5}')
if [[ $disk_size > 75 ]]; then
  echo 'Low disk space on server. Disk usage is currently at $disk_size%' | mail -s 'Low Disk $ip a Alert' admin@example.com "

Problems:

  1. The find command doesn't seem to be working as intended. It's not deleting any files.
codemastermind@ThinkPad-X230:~/scripts$ ./maintenance.sh
find: 'home/': No such file or directory
E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
codemastermind@ThinkPad-X230:~/scripts$
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    When you put a command substitution in double quotes it's run locally, before ssh starts so before there's any connection to your remote server at all. – Charles Duffy Jan 02 '23 at 14:46
  • Also, your question title should be about _the one narrow, specific technical problem your question is about_, not what kind of program you were writing when you encountered that problem; and you should check whether that problem is described in a preexisting, answered question. – Charles Duffy Jan 02 '23 at 14:47
  • 1
    Also, doing an assignment in a transient shell ssh started on a remote server doesn't change the variables you have set in your local script. You want `value=$(ssh ...)`, not `ssh ... 'value=$(...)'`. – Charles Duffy Jan 02 '23 at 14:50
  • 1
    And as a rule, `anything | grep label | awk '{print $5}'` can be replaced with `anything | awk '/label/ { print $5 }'`; awk can do anything grep can do, so there's never a reason to pipe one to the other. – Charles Duffy Jan 02 '23 at 14:55
  • @CharlesDuffy Never a reason to pipe one to the other isn't necessarily true. `grep | awk` can actually be faster when processing large files just because grep's regex filtering is more efficient. It's been about 10 years since ive tested that, though. – jordanm Jan 02 '23 at 16:27
  • @jordanm Implementation-dependent I'll grant. Traditional UNIX awk (like traditional UNIX grep) [used Thompson NFAs, which are very, _very_ fast](https://swtch.com/~rsc/regexp/regexp1.html); but there's a world full of people who can mess things up and often do. – Charles Duffy Jan 02 '23 at 18:59
  • The immediate problem is that when one `ssh` ends, the next one starts over from a clean slate, in the user's home directory. You want to pass all the commands as a single `ssh` command, perhaps as a here document. https://stackoverflow.com/questions/37586811/pass-commands-as-input-to-another-command-su-ssh-sh-etc has some examples. – tripleee Jan 03 '23 at 11:03

0 Answers0