oneline commands

[!TIP]

cat and EOF

[!NOTE|label:references:]

  • Chapter 19. Here Documents
  • bash Heredoc
    • using heredoc with ssh
      ssh -T user@host.com << EOF
      echo "The current local working directory is: $PWD"
      echo "The current remote working directory is: \$PWD"
      EOF
      
  • * POSIX.1 states
    ...an operand naming a file can be specified as '-', which means to use the standard input instead of a named file ....
    
  • kubectl apply from stdin

    [!NOTE|label:references:]

    $ cat << 'EOF' | kubectl apply -f -
    ...
    ...
    EOF
    
    # or
    $ kubectl apply -f - << EOF
    ...
    ...
    EOF
    
  • git apply from stdin

    $ cat >> 'EOF' | git apply --inaccurate-eof --ignore-whitespace
    ...
    ...
    EOF
    
    # or
    $ git apply --inaccurate-eof --ignore-whitespace --stat << 'EOF'
    ...
    ...
    EOF
     install |    6 ++----
     1 file changed, 2 insertions(+), 4 deletions(-)
    
  • git apply from clipboard

    [!NOTE|label:references:]

    $ pbpaste | git apply
    
    $ xsel --clipboard --input | git apply
    # or
    $ xclip -selection clipboard -o | git apply
    
  • patch from stdin

    [!NOTE|label:references:]

    $ patch --dry-run --ignore-whitespace << 'EOF'
    ...
    ...
    EOF
    

while read from input

[!NOTE|label:references:]

$ while IFS=\| read -r col1 col2; do echo ">> $col1 .. $col2 <<"; done <<\INPUT
  a|b
  INPUT
>> a .. b <<

tail and timestamp

$ tail -f file | while read line; do echo -n $(date -u -Ins); echo -e "\t$line"; done

backup multiple files

$ cp -bfS.bak filename filename

ssh

  • compress and ssh and extract

    $ tar cf - . | ssh elsewhere tar xf - -C /other/dir
    
    # or: https://www.commandlinefu.com/commands/view/4034/copy-a-folder-tree-through-ssh-using-compression-no-temporary-files
    $ ssh <host> 'tar -cz /<folder>/<subfolder>' | tar -xvz
    
  • tips

    [!NOTE|label:references:]

    # tips
    $ tar cfz - . | ssh otherhost "cd /mydir; tar xvzf -"
    
    # or: https://www.commandlinefu.com/commands/view/1629/pack-up-some-files-into-a-tarball-on-a-remote-server-without-writing-to-the-local-filesystem
    $ tar -czf - * | ssh example.com "cat > files.tar.gz"
    
    # the z-flag to tar does compression. Or you can use -C to ssh:
    $ tar cf - . | ssh -C otherhost "cd /mydir; tar xvf -"
    

find and tar

$ find . -name builds -prune -o -type f -print | tar czf ~/m.tar.gz --files-from -

# or find with maxdepth
$ find . -type f -name "config.xml" -maxdepth 2 -prune -print | tar czf ~/config.xml.130.tar.gz --files-from -

# find with special name
$ find . -name config\.xml -type f -print | tar czf ~/m.tar.gz --files-from -

# and ssh and extract
$ tar cf - . | ssh -C otherhost "cd /mydir; tar xvf -"

find and rename

$ find -iname "*.sh" -exec rename "s/.sh$/.shell/" {} \; -print

find and sort

find and copy

[!TIP]

$ find . -type f -newermt '2023-10-16 00:00:00' -exec cp -a --parents -t /path/to/target "{}" \+

# or
$ diff=$(( ($(date --date "24-02-29" +%s) - $(date --date "231016" +%s) )/(60*60*24) ))
$ find . -type f -daystart -mtime -$((diff+1)) -exec cp -a --parents -t /path/to/target "{}" \+

download and extract

[!TIP|label:references:]

  • gz

    $ wget -O - http://example.com/a.gz    | tar xz
    # or
    $ curl -fsSL http://example.com/a.gz   | tar xz
    # or
    $ curl -fsSL "http://example.com/a.gz" | tar zxvf -
    
    # or: https://www.commandlinefu.com/commands/view/353/extract-tarball-from-internet-without-local-saving
    $ wget -qO - "http://www.tarball.com/tarball.gz" | tar zxvf -
    
  • tar.gz

    $ curl -fsSL https://dlcdn.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz | tar xzf - -C /path/to/targeT
    
  • tar.xz

    $ curl -fsSL https://ftp.gnu.org/gnu/glibc/glibc-2.38.tar.xz | tar -xJf - -C /path/to/target
    
  • zip

    $ curl -fsSL https://downloads.gradle.org/distributions/gradle-8.4-bin.zip | bsdtar xzf - -C /path/to/target
    
    # with password
    $ curl -fsSL https://path/to/file.zip | bsdtar -xzf- --passphrase <PASSWD_OF_ZIP> - -C <EXTRACT_PATH>
    

mirror website

$ wget --mirror --page-requisites --html-extension --convert-links $URL

# https://www.linuxjournal.com/content/downloading-entire-web-site-wget
$ wget --recursive --no-clobber --page-requisites --html-extension --convert-links --restrict-file-names=windows --domains website.org --no-parent sample.com

# or download entire website: https://www.commandlinefu.com/commands/view/901/download-an-entire-website
$ wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com

# https://superuser.com/a/1415765/112396
$ wget --recursive --level 5 --no-clobber --page-requisites --adjust-extension --span-hosts --convert-links --restrict-file-names=windows --domains sample.com --no-parent sample.com

# https://www.commandlinefu.com/commands/view/30/retrieve-a-list-of-all-webpages-on-a-site
$ URL=www.example.com && wget -rq --spider --force-html "http://$URL" && find $URL -type d > url-list.txt && rm -rf $URL
  • download image only
    $ wget -r -l1 --no-parent -nH -nd -P/tmp -A".gif,.jpg" http://example.com/images
    

kubectl apply from stdin

$ cat << EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: $(echo -n 'admin' | base64)
  password: $(echo -n 'password' | base64)
EOF

show 256 colors

$ for code in {0..255}; do echo -e "\e[38;05;${code}m $code: Test"; done)

# or: https://www.commandlinefu.com/commands/view/6138/show-numerical-values-for-each-of-the-256-colors-in-bash
$ for i in {0..255}; do echo -e "\e[38;05;${i}m${i}"; done | column -c 80 -s ' '; echo -e "\e[m"

# or: https://www.commandlinefu.com/commands/view/11759/show-numerical-values-for-each-of-the-256-colors-in-bash-for-bold-and-normal-fonts
$ for code in $(seq -w 0 255); do for attr in 0 1; do printf "%s-%03s %bTest%b\n" "${attr}" "${code}" "\e[${attr};38;05;${code}m" "\e[m"; done; done | column -c $((COLUMNS*2))
# better version
$ for code in $(seq -w 0 255); do for attr in 0 1; do printf "%b%s-%03s%b\n"  "\e[${attr};38;05;${code}m" "${attr}" "${code}" "\e[m"; done; done | column -c $((COLUMNS*3))

# .. zsh ..
# or: https://www.commandlinefu.com/commands/view/5876/show-numerical-values-for-each-of-the-256-colors-in-zsh
$ for code in {000..255}; do print -P -- "$code: %F{$code}Test%f"; done

# or: https://www.commandlinefu.com/commands/view/12471/show-numerical-values-for-each-of-the-256-colors-in-zsh
for i in {0..255}; do echo -e "\e[38;05;${i}m\\\e[38;05;${i}m"; done | column -c 80 -s ' '; echo -e "\e[m"

rm and exclude

$ rm !(*.foo|*.bar|*.baz)

# https://www.commandlinefu.com/commands/view/4576/remove-everything-except-that-file
$ find . ! -name <FILENAME> -delete

# https://www.commandlinefu.com/commands/view/4570/remove-everything-except-that-file
$ ( shopt -s extglob; rm !(<PATTERN>) )

split file to equal size

$ split -b4m file.tgz file.tgz. ; for i in file.tgz.*; do SUBJ="Backup Archive"; MSG="Archive File Attached"; echo $MSG | mutt -a $i -s $SUBJ YourEmail@(E)mail.com

sync mirror

[!NOTE]

$ rsync -aqzH --delay-updates --delete-after  msync.centos.org::CentOS /path/to/local/mirror/root

# stream 9
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-All /path/to/local/mirror/root

# or src
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-nosrc /path/to/local/mirror/root

# exclude debuginfo
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-nodebug /path/to/local/mirror/root

get all declare

[!NOTE|label:references:]

$ declare
$ declare -p
$ declare -xp

# or
$ typeset
$ typeset -p

# or
$ compgen -v
$ compgen -v | while read line; do echo $line=${!line};done
$ compgen -v | while read line; do declare -p $line; done

# or
$ export
$ printenv

[!NOTE|label:references:]

$ set -o posix ; set | awk -F '=' '{ print $1 }'

# or
$ env
$ env | awk -F '=' '{ print $1 }'
$ env | awk -F '=' '{ print $1 }' | tr '\n' ' '

# or
$ printenv

using string as variable name

[!NOTE|label:references:]

  • eval

    $ aa='echo me'
    $ var='aa'
    $ eval echo \$$var
    echo me
    
  • ${!var}

    $ var1="this is the real value"
    $ a="var1"
    $ echo "${!a}"
    this is the real value
    
  • more usage

    $ sunny='''
    \033[38;5;226m    \\   /    \033[0m
    \033[38;5;226m     .-.     \033[0m
    \033[38;5;226m  ― (   )\033[0m
    \033[38;5;226m     `-’     \033[0m
    \033[38;5;226m    /   \\    \033[0m
    '''
    
    $ fewClouds='''
    \033[38;5;226m   \\  /\033[0m
    \033[38;5;226m _ /\"\"\033[38;5;250m.-.    \033[0m
    \033[38;5;226m   \\_\033[38;5;250m(   ).  \033[0m
    \033[38;5;226m   /\033[38;5;250m(___(__) \033[0m
    
    '''
    
    $ codeMap=(
                 ["01"]="sunny"
                 ["02"]="fewClouds"
               )
    $ icon="$(/usr/bin/curl -sg "https://api.openweathermap.org/data/3.0/onecall?lat=37.3541132&lon=-121.955174&units=metric&exclude=hourly,daily,minutely,alerts&appid=${OWM_API_TOKEN}" | jq -r .current.weather[].icon)"
    $ echo ${icon}
    02n
    
    $ echo -e "${!codeMap["${icon:0:-1}"]}"
    
    using string as var name
    1.2.1.2.1 -- using string as var name

<<<, < <(..)

[!TIP]

  • < <( is Process Substitution
    • The difference between <(...) and >(...) is merely which way the redirections are done

< <(..) && > >(..)

[!NOTE]

  • process substitution
  • syntax

    $ command1 < <( command2 )
    # equals to
    $ command2 | command1
    
    # if read from file, then using `< /path/to/file`
    
  • SubShell

  • example:

    $ while read line; do echo "-- ${line} --"; done < <(ls -1)
    
    # equals to: http://mywiki.wooledge.org/BashFAQ/024
    $ ls -1 | while read line; do echo "-- ${line} --"; done
    # equals to
    $ ls -1 | xargs -n1 -i bash -c "echo \"-- {} --\""
    
    # equals to read from file via `< /path/to/file`
    $ ls -1 > ls.txt
    $ while read line; do echo "-- ${line} --"; done < ls.txt
    
$ wc < <(date)
    1       6      29

# same as:
$ date | wc
    1       6      29
  • < <(..)

    [!TIP|label:references:]

    • subshell
    • tips:

      # If commandA can read the data from stdin
      commandB | commandA                 # You can now get the exit code of commandB from PIPESTATUS.
      commandB > >(commandA)              # You can now get the exit code of commandB from $? (or by putting this in an if)
      
      # If commandA cannot read it from stdin, but requires a file argument
      commandB > >(commandA <(cat))       # Again, commandB's exit code is available from $?
      
      # You can also keep commandB's output in memory.  When you do this, you can get commandB's exit code from $? or put the assignment in an if
      b=$(commandB); commandA <<< "$b"    # Here, commandA reads commandB's output from stdin
      
    • common usage

      $ diff <(sort list1) <(sort list2)
      
      # or
      $ while read file; do
          echo -e "\n\033[1;33m${file}\n---\033[0m"
          sed -n "/<<<<<<< HEAD/,/>>>>>>> /!d;=;p" ${file}
          echo -e "\n\033[1;33m---\033[0m"
        done < <(git grep --no-color -l "<<<<<<< HEAD")
      
  • > >(..)

    [!TIP]

    • Process Substitution
      • >(...) is used less frequently; the most common situation is in conjunction with tee(1).
      • >(...) is handy when redirecting the output to multiple files, based on some criteria.
    # For example:
    $ some_command | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null
    

parameter substitution

EXPR DESCRIPTION
${variable-default} if variable is unset, use default
${variable=default} if variable is unset, set variable to default
${variable+alt} if variable is set, use alt, else use null string
${variable:-default} with ":[-=+]", condition takes also "declared but null"

arguments substitution

EXPR DESCRIPTION
$@
           p1 p2 p3 p4 p5 p6 
${@: 0}
 ./args.sh p1 p2 p3 p4 p5 p6 
${@: 1}
           p1 p2 p3 p4 p5 p6 
${@: 2}
              p2 p3 p4 p5 p6 
${@: 2:1}
              p2             
${@: 2:2}
              p2 p3          
${@: -2}
                       p5 p6 
${@: -2:1}
                       p5    
${*: -1} or ${@: $#}
                          p6 
${@: 1:$#-1}
           p1 p2 p3 p4 p5    
  • sample with uncertain parameters

    local opt=''
    local loop=true
    local path params
    
    while ${loop} && [[ $# -gt 0 ]]; do
      case "$1" in
        -*) opt+="$1 "; shift;;
         *) loop=false       ;;
      esac
    done
    
    if [[ 1 = "$#" ]]; then
      path=''
      params="$1"
    else
      path=${*: -1}
      params=${*:1:$#-1}
    fi
    
    sample script c.sh
    echo '---------------- before shift -------------------'
    echo ".. \$# : $#"
    echo ".. \$@ : $@"
    echo ".. \$* : $*"
    
    echo '---------------- after shift -------------------'
    opt=''
    ss=''
    loop=true
    
    while $loop && [[ $# -gt 0 ]]; do
      case "$1" in
        -*) opt+="$1 "; shift;;
         *) loop=false       ;;
      esac
    done
    
    echo ".. \$#   : $#"
    echo ".. \$@   : $@"
    echo ".. \$*   : $*"
    echo ".. \$opt : $opt"
    
    if [[ 0 = "$#" ]]; then
      echo -e "\033[0;33mERROR: must provide at least one non-opt param\033[0m"
      exit 2
    elif [[ 1 = "$#" ]]; then
      path=''
      params="$1"
    else
      path=${*: -1}
      params=${*:1:$#-1}
    fi
    
    echo '---------------- result -------------------'
    echo ">> opt    : ${opt}"
    echo ">> params : ${params}"
    echo ">> path   : ${path}"
    
    result
    $ ./c.sh -1 -2 --3-4 a b c d e
    ---------------- before shift -------------------
    .. $# : 8
    .. $@ : -1 -2 --3-4 a b c d e
    .. $* : -1 -2 --3-4 a b c d e
    ---------------- after shift -------------------
    .. $#   : 5
    .. $@   : a b c d e
    .. $*   : a b c d e
    .. $opt : -1 -2 --3-4
    .. $ss  : a b c d e
    ---------------- result -------------------
    >> opt    : -1 -2 --3-4
    >> params : a b c d
    >> path   : e
    
    $ ./c.sh aa bb
    ---------------- before shift -------------------
    .. $# : 2
    .. $@ : aa bb
    .. $* : aa bb
    ---------------- after shift -------------------
    .. $#   : 2
    .. $@   : aa bb
    .. $*   : aa bb
    .. $opt :
    .. $ss  : aa bb
    ---------------- result -------------------
    >> opt    :
    >> params : aa
    >> path   : bb
    
    $ ./c.sh -1
    ---------------- before shift -------------------
    .. $# : 1
    .. $@ : -1
    .. $* : -1
    ---------------- after shift -------------------
    .. $#   : 0
    .. $@   :
    .. $*   :
    .. $opt : -1
    ERROR: must provide at least one non-opt param
    

quotas

  • ${@@Q}

    # a.sh
    line="${@@Q}"
    echo $line
    
    $ bash a.sh -a -b --c='1 2 3'
    '-a' '-b' '--c=1 2 3'
    
    # https://stackoverflow.com/a/39463371/2940319
    $ expand-q() { for i; do echo ${i@Q}; done; }
    $ expand-q -a -b --c='1 2 3'
    '-a'
    '-b'
    '--c=1 2 3'
    
    # https://stackoverflow.com/a/72745869/2940319
    function quote() {
      local QUOTED_ARRAY=()
      for ARGUMENT; do
        case ${ARGUMENT} in
          --*=*)
            QUOTED_ARRAY+=( "${ARGUMENT%%=*}=$(printf "%q" "${ARGUMENT#*=}")" )
            shift
          ;;
          *)
            QUOTED_ARRAY+=( "$(printf " %q" "${ARGUMENT}")" )
          ;;
        esac
      done
      echo ${QUOTED_ARRAY[@]}
    }
    
    ARGUMENTS="$(quote "${@}")"
    echo "${ARGUMENTS}"
    
  • printf " %q" "${@}"

    [!NOTE]

    while test -n "$1"; do
      case "$1" in
        -- ) shift; GIT_OPT=$(printf " %q" "${@}"); break ;;
      esac
    done
    GIT_OPT="${GIT_OPT#\ \'\'}"
    
    # https://stackoverflow.com/a/39463371/2940319
    $ params-q() { printf "%q\n" "$@"; }
    $ params-q -a -b --c='1 2 3'
    -a
    -b
    --c=1\ 2\ 3
    
  • String replacement

    [!TIP]

    # a.sh
    while test -n "$1"; do
      case "$1" in
        -- ) shift; GIT_OPT="$@";;
        *  ) shift;;
      esac
    done
    
    GIT_OPT=$(echo "${GIT_OPT}" |
                 sed -r 's/\s+--/\n--/g' |
                 sed -r "s/^([^=]+)=(.+)$/\1='\2'/g" |
                 sed -e 'N;s/\n/ /'
              )
    echo $GIT_OPT
    
    $ bash a.sh -a -b -- --c='1 2 3'
    --c='1 2 3'
    
    # https://stackoverflow.com/a/8723305/2940319
    # a.sh
    C=''
    for i in "$@"; do
        i="${i//\\/\\\\}"
        C="$C \"${i//\"/\\\"}\""
    done
    echo $C
    
    $ bash ~/a.sh -a -b --c='1 2 3'
    "-a" "-b" "--c=1 2 3"
    

string manipulations

EXPR DESCRIPTION
${#string} length
${string:position} substring, or positional parameter with $* and $#
${string:position:length} substring
${string#substring} deletes shortest match of $substring from front of $string
${string##substring} same but longest match
${string%substring} shortest from back
${string%%substring} longest from back
${string/substring/replacement} replace first match
${string//substring/replacement} replace all matches
${string/#substring/replacement} replace if matches front end of $string
${string/%substring/replacement} replace if matches back end of $string
${var^} uppercase first char
${var^^} uppercase all chars
${var,} lowercase first char
${var,,} lowercase all chars

compound comparison

SC2155

  • problematic code:
    ([ "$x" ] || [ "$y" ]) && [ "$z" ]
    
  • correct code:
    { [ "$x" ] || [ "$y" ]; } && [ "$z" ]
    
  • example

SC2155

  • problematic code:
    export foo="$(mycmd)"
    
  • correct code:
    foo="$(mycmd)"
    export foo
    

escape code

[!TIP] references:

ESCAPE CODE LANGUAGE DESCRIPTION
\x1b Node.js hex char
\x1b Node.js w/ TS hex char
\u001b Python hex char
\033 GNU Cpp octal char
\033 ANSI C octal char
\033 POSIX-compliant shells octal char
\e Bash -
\c[ - control char

echo

echo var name from variable

[!NOTE]

  • typeset

    $ typeset -p "${foo}"$
    declare -- bar="baz"
    
  • eval \$$

    $ eval echo \$$foo
    baz
    
    • more:
      $ echo \$$foo
      $bar
      # or
      $ echo '$'$foo
      $bar
      
  • {!parameter}

    $ echo "${!foo}"
    baz
    

echo var name

[!NOTE]

  • typeset

    $ typeset -p c2
    declare -- c2="cc"
    
  • {!parameter@}

    $ echo "${!c@}"
    c1 c2
    
    $ echo "${!a@}"
    a1 a2
    
  • more

    superEcho() {
      echo "$1 = ${!1}"
    }
    
    $ superEcho foo
    foo = bar
    $ superEcho bar
    bar = baz
    

ls

[!NOTE|label:references]

# show file only
$ ls -p | command grep -v /

# show folder only
$ ls -p | command grep / | command grep "^."

# show all files ( including hidden )
$ ls -Ap | command grep -v / | command grep "^."

# show all folders ( including hidden )
$ ls -Ap | command grep / | command grep "^."

# show hidden folder only
$ ls -Ap | command grep / | command grep "^\." | command grep "\."

# show hidden file only
$ ls -Ap | command grep -v / | command grep "^\." | command grep "\."

# show all including hidden
$ ls -Ap

# show hidden file and folder
$ ls -Ap | command grep "^\."

tricky

alias for sudo

[!TIP|label:references:]

alias sudo='sudo '

get md5sum

env

  • HISTTIMEFORMAT

    # https://www.commandlinefu.com/commands/view/3642/save-date-and-time-for-each-command-in-history
    export HISTTIMEFORMAT="%h/%d-%H:%M:%S "
    
    # or: YYYY-MM-DD HH:MM:SS : https://www.commandlinefu.com/commands/view/3646/save-date-and-time-for-each-command-in-history
    $ export HISTTIMEFORMAT='%F %T '
    
  • GREP_OPTIONS

    $ GREP_OPTIONS='-D skip --binary-files=without-match --ignore-case'
    

shortcuts

man

Copyright © marslo 2020-2025 all right reserved,powered by GitbookLast Modified: 2026-03-06 01:05:54

results matching ""

    No results matching ""