⬅️ **[[$-Tools|Tools]]** *** # Bash - [YourOwnLinux - Bash Array](http://www.yourownlinux.com/2016/12/bash-scripting-arrays-examples.html) ## [[zsh]] ## Starting a script - **Issue: `Syntax error: "(" unexpected` when creating an array:** When you use `./scriptname.sh` it executes with `/bin/bash` as in the first line with `#!`. But when you use sh scriptname.sh it executes sh, not bash. ```bash #!/usr/bin/env bash # Use set -o errexit (a.k.a. set -e) to make your script exit when a command fails. set -o errexit # Use set -o nounset (a.k.a. set -u) to exit when your script tries to use undeclared variables. set -o nounset # Use set -o xtrace (a.k.a set -x) to trace what gets executed. Useful for debugging. # set -o xtrace # Use set -o pipefail in scripts to catch mysqldump fails in e.g. mysqldump |gzip. The exit status of the last command that threw a non-zero exit code is returned. set -o pipefail ``` ### Run a shell script as a different user `/bin/su -c "/path/to/backup_db.sh /tmp/test" - postgres` ### Run Oracle SQL script and exit from sqlplus.exe via command prompt `echo exit | sqlplus user/pass@connect @scriptname` ## Handling exit codes - [Bash get exit code of command on a Linux / Unix](https://www.cyberciti.biz/faq/bash-get-exit-code-of-command/) - Output exit code of last command: `echo $?` ## Array ```bash ### Array anlegen myArray=("cat" "dog" "mouse" "frog) ### loop through it: for i in ${!myArray[@]}; do echo "element $i is ${myArray[$i]}" done ### Output: element 0 is cat element 1 is dog element 2 is mouse element 3 is frog ``` ## File handling ### Copy latest file of folder Source: https://unix.stackexchange.com/questions/195304/how-do-i-copy-the-latest-file-from-one-directory-to-another Here, `ls -d` gives the absolute path. In your command, as `ls` is not returning absolute paths, you must run that from the source directory to get the file copied. As you have run it from some other directory that does not have the file, the error `No such file or directory` being shown. Also as you have spaces in the path we need to quote `ls -dtr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/* | tail -1` so that shell does not do word splitting on the output of it. ```bash cp -p "`ls -dtr1 "$SRC_DIR"/* | tail -1`" "$DEST_DIR" ``` ### Remain original file timestamps If you want to preserve the original timestamps, use ```bash touch -r <original_file> <new_file> ``` This copies the timestamps from another file. ### Read file line by line ```sh while IFS= read -r line; do printf '%s\n' "$line" done < input_file ``` ## Variables - Set a new variable: `PARAM_APP1="app1"` - Get value from Linux Command: `isHddThere=$(sudo blkid | grep '1a7cdbbc-af98-4eb7-b195-e84fa1f87460')` ## Functions and Scripts - [Ryans Tutorials - Functions](https://ryanstutorials.net/bash-scripting-tutorial/bash-functions.php) ### Create Scripts during execution ```bash testVar="Variable for the dynamically created file" cat <<EOT >/path/to/file.md # Test Header - Text1 - Text2 - Here is the content of the testVar = "${testVar}" - This content is then created during execution. EOT ``` ## User interaction ### Input from user `read <variable_name` ### Select Menu The select construct generates a menu from a list of items. It has almost the same syntax as the for loop: ```bash select ITEM in [LIST] do [COMMANDS] done ``` The [LIST] can be a series of strings separated by spaces, a range of numbers, output of a command, an array, and so on. A custom prompt for the select construct can be set using the PS3 environment variable. When the select construct is invoked, each item from the list is printed on the screen (standard error), preceded with a number. ### Scripts expecting User input Here is the call of a script on the CLI with EOF containing the 5 User inputs per line: ```bash sh script_name.sh <<EOF Input1 Input2 Input 4 EOF ``` ## Controls ### If..else **Default example:** ```bash singleInput="" # read user input read singleInput if [ "$singleInput" = "" ] then singleInput="null" else summary="$summary \n- $singleInput" fi ``` **Some OR-Conditions:** ```bash if [ $1 == ${PARAM_APP1} -o $1 == ${PARAM_APPN} -o $1 == ${PARAM_DB} ]; then (...) fi ``` **Check if file / folder exists:** ```bash if [ -f /apps/SD/Last_Delivery.tar ]; then echo "|-- Delete old /apps/SD/Last_Delivery.tar" rm -f /apps/SD/Last_Delivery.tar fi echo "|--- Create temporary folder ${DELIVERY_BASE_RTDIR_TEMP}" if [ ! -d ${DELIVERY_BASE_RTDIR_TEMP} ]; then mkdir -p ${DELIVERY_BASE_RTDIR_TEMP} fi ``` ### Switch..Case ```bash read category fileName="" case "$category" in 1) fileName="Privat" ;; 2) fileName="Natur" ;; 3) fileName="Finanzen" ;; 4) fileName="Arbeit" ;; 5) fileName="Bib" ;; *) echo "Falsche eingabe" exit 1 ;; esac ``` ## Loops ### While Loop ```bash summary="" singleInput="" while [ "$singleInput" != "null" ] do read singleInput if [ "$singleInput" = "" ] then singleInput="null" else summary="$summary \n- $singleInput" fi done; ``` ## Text and Formats ### Concat text in string `output="\n### $(date +'%F') $title $articleLine $summary"` ### Formatted `echo` output without `\n` etc. `echo -e $output` ### Output into a file - Concat to existing file ` >> ` - `echo -e $output >> $filePath/$fileName-$(date +'%Y-%m')-news.md` - Overwrite existing file ` > ` ### Format date - `$(date +'%A %F %T %Z')` is `Friday 2020-01-24 21:57:19 CET` - `$(date +'%F')` is `2020-01-24` - `$(date +'%u')` is `1` for Monday, etc. # *** Related: - [[$-Software|Software]] - [[$-Linux|Linux]]