Evan Harmon - Memex

Shell Scripting

  • Naming Convention: script_name.sh
    • Linix doesnt use extensions per se like Windows but the .sh is a naming convention.
  • Store Scripts
    • Personal ones for my account, ~/bin. System-wide ones go in /usr/local/bin or /usr/local/sbin as appropriate (scripts which should only be run as root go in sbin, while scripts intended to help ordinary users go in bin
    • Store them anywhere you want, but add that location to your PATH environment variable so you can run them with just the script_name.sh
    • Linux
      • Dropbox/Programming/Bash/Scripts?
      • or: ~/Scripts
      • More Traditional: ~/bin
        • I think a lot of distros will automatically add this to PATH if you create a bin folder in your home diretory.
        • I think this code is in operation/default in a lot of distros:
          • # set PATH so it includes user's private bin if it exists if [ -d "\(HOME/bin" ] ; then PATH="\)HOME/bin:$PATH" fi
    • Mac
      • Dropbox/Programming/Bash/Scripts?
    • Windows
  • Create a Script
    • #!/bin/bash
      • # indicates comment, but the follwing ! means bypass the # symbol and run the follwing commands with BASH as if you were at the terminal regularly.
    • #!/bin/sh
      • Sometimes you see this which usually works the same as #!/bin/bash but there might be bugs if there are bash specific things not supported in the system shell.
      • I think it is a symlink to the currently configured system shell which is usually bash, but not necessarily. /bin/sh is technically the sh that bash superseded.
      • Some recommend using this because on certain distros like Ubuntu and Debian it links to dash which supposedly runs quicker and is more secure. Ubuntu's normal login shell is still bash, though.
      • So, in sum: use #!/bin/bash when you need bash-specific stuff. Otherwise #!/bin/sh is often better because it might point to dash which is faster and more secure.
  • Make Script Executable
    • chmod +x scriptname.sh or chmod 0755 scriptname.sh
  • Make a given BASH command that normally requires a sudo password not require a password
    • Create /etc/sudoers.d/some_new_file
      • and add someuser ALL=NOPASSWD: /bin/systemctl restart some-demo.service to make someuser not need a password to systemctl restart some-demo.service:
      • Then you can run systemctl restart some-demo.service without needing to type in a password but you still need to precede it with sudo!
    • E.g., my neighbor-share deploy.py build and deploy and transfer and restart script
  • File Paths for Running Scripts
    • < script.sh bash
      • Always works but tedious to type
    • ./script.sh
      • Works if script starts with shebang #!/bin/bash and its chmodded as x
      • Script also needs to be in current working directory
    • /path/to/script.sh
      • Same as ./script.sh but also works when the script isnt in working directiory
    • script.sh
      • Works when the directory that the script is in is listed in the PATH variable
    • Default Directories for Scripts
      • /usr/local/bin
        • I think by default in PATH and maybe the conventional way/place of storing scripts.
      • You can make a symbolic link to a script - if its in a local/cloned code repo e.g. - and just put it in /usr/local/bin
  • Option: Add functions directly to ~/.bashrc file instead of creating a whole script
    • Sometimes only way to do something like changing the working directory of the parent instance instead of that shell script's own instance of BASH
  • Store passwords in external file so script is reusable
    • could make the script or password file have protected permissions?
    • I think the main thing is that the server itself should be secured
  • Automation/Startup
    • Cron
    • rc.local
      • run a command or program at boot - add commands to the rc.local file (/etc/rc.local)
        • add commands to file but leave exit 0
        • if you have a continuously running program you need to add an ampersand like:
          • python /home/pi/myscript.py &
          • Otherwise, the script will not end and the Pi will not boot. The ampersand allows the command to run in a separate process and continue booting with the process running.
    • Create your own system daemon service thing
      • If you want to run an app, you probably want to do a daemon so it shuts down properly v
    • Shell `at`, `batch`, `atq`, and `atrm` commands for scheduling
    • bashrc
  • Example Script for Meep
    • #!/bin/sh aliases=" alias shapi='docker container exec -it meep-backend_api_1 /bin/ash -l'  #shell into api\n alias shweb='docker container exec -it meep-backend_web_server_1 /bin/bash'  #Shell into web\n alias shdb='docker container exec -it meep-backend_db_1 psql -U meep -h meep-backend_db_1 -d meep_api'  #shell into db \n alias shtdb=''  #shell into test db? \n alias dbreset='docker container exec meep-backend_api_1 python /meep/api/src/db_operations.py reset dev'  #reset the dev db \n alias dcu='docker-compose up --build -d'  #docker-compose up \n alias dcd='docker-compose down'  #docker-compose down \n alias dcr='docker-compose down && docker-compose up --build -d'  #docker-compose down \n alias tests='docker exec -it meep-backend_api_1 pytest -v'  #shell into api container and pytest -v \n alias testsnv='docker exec -it meep-backend_api_1 pytest'  #shell into api container and pytest \n " arg1=1;&nbsp;arg2=$2 if&nbsp;\[&nbsp;\\(arg1&nbsp;=&nbsp;"copytobashprofile"&nbsp;];&nbsp;then &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\\)aliases&nbsp;&gt;&gt;&nbsp;\~/bashprofile.txt &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;Aliases&nbsp;successfully&nbsp;copied&nbsp;to&nbsp;your&nbsp;.bash\_profile elif&nbsp;\[&nbsp;\\(arg1&nbsp;=&nbsp;"copytobashrc"&nbsp;];&nbsp;then &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\\)aliases&nbsp;&gt;&gt;&nbsp;\~/bashrc.txt &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;Aliases&nbsp;successfully&nbsp;copied&nbsp;to&nbsp;your&nbsp;.bashrc&nbsp;file elif&nbsp;\[&nbsp;arg1 = "dcu" ]; then     docker-compose up --build -d else     echo Unrecognized command fi
  • Bash scripts can take arguments just like bash commands do
    • $1 is the first argument after script
    • $2 second argument etc
    • Eg
      • Script.sh argument1 argument2
    • getopt for system cli switches
Shell Scripting
Interactive graph
On this page
Shell Scripting