This shows you the differences between two versions of the page.

Link to this comparison view

start:development:scripting_languages:shells [2020/04/16 19:28] (current)
jrutte02 created
Line 1: Line 1:
 +====== Scripting Bash ======
 +[[|Bash]] - or **B**ourne **A**gain **SH**ell - is the //standard shell// on our high-performance clusters. We do not attempt to provide full documentation, here, in the wiki. Instead, we like to point to a few great resources:
 +  * [[|Advanced Intro]]
 +  * [[|Introductory HowTo]] 
 +Both are dated, but still good.
 +===== Our Courses =====
 +As our HPC introductory course and many others heavily rely on Bash, we provide introductory courses for Bash (dubbed "Bash-Crash"), too. These are intended to provide the background for the HPC introductory course (and any HPC computing) and are intended for those (employees and students in Rhineland Palatinate, alike) with an interest in HPC. You can enroll, [[|here]].
 +===== Other Shells =====
 +Some projects suggest or impose to use a different shell. This is, of course, possible on our systems, too.
 +List of available shells((In case one is missing or you would like to use a different one, let us know.)) and the shebang to use:
 +^ Shell ^ Call for interactive session((Some shells provide an ''-i'' flag, which can be supplied to enforce an interactive shell.))        ^ Shebang                ^
 +| **B**ourne **A**gain **SH**ell (Bash)| ''$ bash'' | ''#!/bin/bash''  |
 +| C-Shell                        | ''$ csh''    | ''#!/bin/csh ''        |
 +| Korn Shell                     | ''$ ksh''    | ''#!/bin/ksh ''        |    
 +| TENEX-C-Shell                  | ''$ tcsh''   | ''#!/bin/tcsh''        |
 +| Z-Shell                        | ''$ zsh''    | ''#!/bin/zsh''         |
 +<callout type="info" title="You may use any of these shells - be advised, however, that" icon="true">
 +  * We only support Bash.
 +  * Some Cluster features (e.g. the environment exported by SLURM) might not be available.
 +If you choose to use a different shell - in this example ''zsh'' -- you can try this snippet (in ''bash''):
 +<code bash>
 +if [[ $- == *i* ]]; then
 +  if [[ "$SLURM_CLUSTER_NAME" == "" ]]; then
 +    if [ -z ${SBASH+x} ]; then
 +        export SHELL=/bin/zsh
 +        exec /bin/zsh -l
 +    fi
 +  fi
 +It activates the ''zsh'', e.g. upon login, when placed in the ''.bashrc''-file. Calling
 +<code zsh>
 +export SBASH=1 && bash
 +will let you return to ''bash'' at any time.
 +===== Best Practices =====
 +<WRAP center round info 90%>
 +This is a completely arbitrary list - and only applicable to Bash! We make no claim for it to be complete.
 +  - //Always comment your code//\\ \\ This is a recommended practice which is not only applied to shell scripting but all other kinds of programming. Writing comments in a script helps you or some else going through your script understand what the different parts of the script do.\\ \\ For starters, comments are defined using the ‘#’ sign.
 +  - //Make a script exit when it fails//\\ \\ Sometimes bash may continue to execute a script even when a certain command fails, thus affecting the rest of the script (may eventually result in logical errors). Use the line below to exit a script when a command fails: <code bash>#let script exit if a command fails
 +set -o errexit 
 +set -e</code>\\ Add ''|| true'' to commands that you allow to fail.
 +  - //Make a script exit when bash uses an undeclared variable//\\ \\ This is frequently a cause for confusion: Applications crash, when hitting an exception, e.g. an undeclared variable. So does the shell, doesn’t it?\\ \\ Shells – and Bash – are different. This may be desired or not. Yet, it is not just a source of confusion. It is a cause for a number of tickets (read: help request for the HPC team), too. This is because variables can be undeclared unintentionally. Therefore use the following line to instruct bash to exit a script when it attempts to use an undeclared variable:<code bash>#let script exit if an unsed variable is used
 +set -o nounset
 +set -u</code>
 +  - //Make broken pipes fail//\\ \\ Use ''set -o pipefail'' in scripts to catch command fails in e.g. in ''first_command | grep <pattern>''. The exit status of the last command that threw a non-zero exit code is returned.\\ 
 +  - //Surround your variables with {}//\\ \\ Otherwise bash will try to access the ''$ENVIRONMENT_app'' variable in expansions like ''/path/$ENVIRONMENT_app'', whereas you probably intended ''/path/${ENVIRONMENT}_app''.
 +  - //Surround your variables with quotes//\\ \\ For example in <code bash>if [ "${NAME}" = "Kevin" ]</code> , because if ''$NAME'' isn't declared, bash will throw a syntax error (also see nounset). Use '':-'' if you want to test variables that could be undeclared. For instance: <code bash>if [ "${NAME:-}" = "Kevin" ]</code> will set ''$NAME'' to be empty if it's not declared. You can also set it to ''noname'' like so <code bash>if [ "${NAME:-noname}" = "Kevin" ]</code>
 +  - //Use functions in Scripts//\\ \\ Except for very small scripts (with a few lines of code), always remember to use functions to modularize your code and make scripts more readable and reusable.\\ \\ The syntax for writing functions is as follows:<code bash>function check_integrity(){
 + command1; 
 + command2;
 +}</code> OR <code bash>check_integrity(){
 + command1; 
 + command2;
 +}</code> For single line code, use termination characters after each command like this:<code bash>check_integrity(){ command1; command2; }</code>
 +  - //Use ''$(command)'' instead of legacy ''`command`'' for Substitution//\\ \\ Command substitution replaces a command with its output. Use ''$(command)'' instead of backquotes ''`command`'' for command substitution.\\ \\ This even allows nesting commands without loosing your sanity:<code bash>parent=$(basename $(dirname $PWD))</code>
 +  - //Use read-only to declare static variables//\\ \\ A static variable doesn’t change; its value can not be altered once it’s defined in a script:<code bash>readonly my_constant=42</code>
 +There are lots of odds and ends and particularly for new users this can be overwhelming. Be sure to check out our [[|introductory courses]].
 +====== Integrity Checking of Shell Scripts ======
 +However good a writer may be – she will always make mistakes. Now you can always invoke a script with ''bash -n <script>'' to check the script is without errors. Yet, just the other day we installed [[|“shellcheck”]] on the login-nodes. If you run ''shellcheck <options> <script>'' it will spot (most likely) a number of code smells, potential errors and real ones – and sort them according to their respective severity.
  • start/development/scripting_languages/shells.txt
  • Last modified: 2020/04/16 19:28
  • by jrutte02