Shell

Block comment

With “END” being just an example of any random string that must not appear in the commented section:

: << 'END'
sleep 1
END

Iterate over a list as a string

Different options:

# option 1, without variable
for x in a b c; do echo $x; done
 
# option 2, with string
list="a b c"
for x in $list; do echo $x; done         # only works with sh and bash
for x in ${=list}; do echo $x; done      # only works with zsh
for x in $(echo $list}; do echo $x; done # works with any shell
 
# option 3, with an array
list=(a b c)
for x in $list; do echo $x; done

Do something recursively on all files

Use find, with {} being the file name:

find . -type f -exec <command> {} \;
find -iname "<pattern>" -exec <command> {} \;

Manual solution:

#!/bin/sh
 
function search_dir()
{
    DIR=$1;
 
    for file in $DIR/*; do
        if [[ -f $file ]]; then
            echo "Do something with $file"
        fi;
    done
 
 
    for element in $DIR/* ; do
        if [[ -e $element && -d $element && \
            $(basename "$element") != ".." && \
            $(basename "$element") != "." ]]; then
 
            search_dir "$element";
        fi;
    done;
}
 
search_dir "."

Misc

  • Default value for variable:
    ${<variable>:-<default-value>}
  • Get directory of current script (for instance in order to run a script that is stored in the same directory, or in a known relative path):
    BASEDIR=$(dirname "$0")
  • echo to stderr, just redirect the output:
    echo "foo" 1>&2
  • Convert dash-time to ISO (2024-04-21_15-50-30 to 2024-04-21T15:50:30, for instance to use it as input for date):
    sed -r "s/([0-9]{4})-([0-9]{2})-([0-9]{2})_([0-9]{2})-([0-9]{2})-([0-9]{2})/\1-\2\-3T\4:\5:\6/"
  • Get target name of symbolic link:
    readlink <symbolic-link>
  • Execute command:
    var=`cat file`
    var=$(cat file)
  • Evaluate mathematical expression (zsh also supports floating-point operations):
    echo $((2*3))
  • time with redirected output (also works for groups of commands):
    time (cat file1 > file2)
    time (cat file1 > /dev/null; sync)
  • Check number of arguments and print usage:
    if [[ $# -lt 2 ]]; then
            echo "Usage: foo.sh <arg1> <arg2>" 1>&2
            exit 1
    fi
  • Load command output as a file:
    diff <(grep x file1) <(grep y file2)
  • Remove extension from file name:
    ${f%.png} # with all shells
    ${f:r}    # only zsh
linux/shell.txt · Last modified: 2024/12/11 09:40 by cyril
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0