Difference between revisions of "Bash/Functions"

From ArchWiki
Jump to: navigation, search
(update zh-cn/tw interlanguage links to zh-hans/hant, see Help talk:I18n#Chinese interlanguage links)
(Extract: link Archiving and compression tools#Convenience tools instead of duplicating it)
 
(One intermediate revision by the same user not shown)
Line 9: Line 9:
 
To set {{ic|trap}} to intercept a non-zero return code of the last program run:
 
To set {{ic|trap}} to intercept a non-zero return code of the last program run:
  
{{hc|~/.bashrc|
+
EC() {
EC() {
+
echo -e '\e[1;33m'code $?'\e[m\n'
echo -e '\e[1;33m'code $?'\e[m\n'
+
}
}
+
trap EC ERR
trap EC ERR
 
}}
 
  
 
== Compile and execute a C source on the fly ==
 
== Compile and execute a C source on the fly ==
Line 20: Line 18:
 
The following function will compile (within the {{ic|/tmp/}} directory) and execute the [[wikipedia:C (programming language)|C]] source argument on the fly (and the execution will be without arguments). And finally, after program terminates, will remove the compiled file.
 
The following function will compile (within the {{ic|/tmp/}} directory) and execute the [[wikipedia:C (programming language)|C]] source argument on the fly (and the execution will be without arguments). And finally, after program terminates, will remove the compiled file.
  
{{hc|~/.bashrc|<nowiki># Compile and execute a C source on the fly
+
<pre># Compile and execute a C source on the fly
 
csource() {
 
csource() {
 
[[ $1 ]]    || { echo "Missing operand" >&2; return 1; }
 
[[ $1 ]]    || { echo "Missing operand" >&2; return 1; }
Line 28: Line 26:
 
rm "$output_path";
 
rm "$output_path";
 
return 0;
 
return 0;
}</nowiki>}}
+
}</pre>
  
 
== Extract ==
 
== Extract ==
Line 34: Line 32:
 
The following function will extract a wide range of compressed file types.  and use it with the syntax {{ic|extract <file1> <file2> ...}}
 
The following function will extract a wide range of compressed file types.  and use it with the syntax {{ic|extract <file1> <file2> ...}}
  
{{hc|~/.bashrc|<nowiki>
+
<pre>
 
extract() {
 
extract() {
 
     local c e i
 
     local c e i
Line 69: Line 67:
 
     return "$e"
 
     return "$e"
 
}
 
}
</nowiki>}}
+
</pre>
  
 
{{Note|Make sure {{ic|extglob}} is enabled: {{ic|shopt -s extglob}}, by adding it to the {{ic|~/.bashrc}} (see [[gregswiki:glob#Options_which_change_globbing_behavior]]).}}
 
{{Note|Make sure {{ic|extglob}} is enabled: {{ic|shopt -s extglob}}, by adding it to the {{ic|~/.bashrc}} (see [[gregswiki:glob#Options_which_change_globbing_behavior]]).}}
  
Another way to do this is to install a specialized package. For example:
+
Another way to do this is to install a specialized package, see [[Archiving and compression tools#Convenience tools]].
 
 
* {{Pkg|unp}} - package from the official repositories which contains a Perl script
 
* {{Pkg|atool}}
 
* {{AUR|dtrx}}
 
  
 
== cd and ls in one ==
 
== cd and ls in one ==
Line 84: Line 78:
 
In this example we will name it {{ic|cl}} (change list) and show an error message if the specified directory does not exist.
 
In this example we will name it {{ic|cl}} (change list) and show an error message if the specified directory does not exist.
  
{{hc|~/.bashrc|<nowiki>
+
<pre>
 
cl() {
 
cl() {
 
local dir="$1"
 
local dir="$1"
Line 94: Line 88:
 
fi
 
fi
 
}
 
}
</nowiki>}}
+
</pre>
  
 
Of course the ''ls'' command can be altered to fit your needs, for example {{ic|1=ls -hall --color=auto}}.
 
Of course the ''ls'' command can be altered to fit your needs, for example {{ic|1=ls -hall --color=auto}}.
Line 100: Line 94:
 
== Simple note taker ==
 
== Simple note taker ==
  
{{hc|~/.bashrc|<nowiki>
+
<pre>
 
note () {
 
note () {
 
     # if file doesn't exist, create it
 
     # if file doesn't exist, create it
Line 118: Line 112:
 
     fi
 
     fi
 
}
 
}
</nowiki>}}
+
</pre>
  
 
== Simple task utility ==
 
== Simple task utility ==
Line 124: Line 118:
 
Inspired by [[#Simple note taker]]
 
Inspired by [[#Simple note taker]]
  
{{hc|~/.bashrc|<nowiki>
+
<pre>
 
todo() {
 
todo() {
 
     if [[ ! -f $HOME/.todo ]]; then
 
     if [[ ! -f $HOME/.todo ]]; then
Line 145: Line 139:
 
     fi
 
     fi
 
}
 
}
</nowiki>}}
+
</pre>
  
 
== Calculator ==
 
== Calculator ==
  
{{hc|~/.bashrc|<nowiki>
+
calc() {
calc() {
+
    echo "scale=3;$@" | bc -l
    echo "scale=3;$@" | bc -l
+
}
}
 
</nowiki>}}
 
  
 
== Kingbash ==
 
== Kingbash ==
Line 161: Line 153:
 
Install {{AUR|kingbash-gb-git}} from the [[AUR]], then insert the following into your {{ic|~/.bashrc}}:
 
Install {{AUR|kingbash-gb-git}} from the [[AUR]], then insert the following into your {{ic|~/.bashrc}}:
  
{{hc|~/.bashrc|<nowiki>
+
<pre>
 
function kingbash.fn() {
 
function kingbash.fn() {
 
     echo -n "KingBash> $READLINE_LINE" #Where "KingBash> " looks best if it resembles your PS1, at least in length.
 
     echo -n "KingBash> $READLINE_LINE" #Where "KingBash> " looks best if it resembles your PS1, at least in length.
Line 170: Line 162:
 
}
 
}
 
bind -x '"\t":kingbash.fn'
 
bind -x '"\t":kingbash.fn'
</nowiki>}}
+
</pre>
  
 
== IP info ==
 
== IP info ==
Line 176: Line 168:
 
Detailed information on an IP address or hostname in bash via http://ipinfo.io:
 
Detailed information on an IP address or hostname in bash via http://ipinfo.io:
  
{{bc|<nowiki>
+
ipif() {  
ipif() {  
+
    if grep -P "(([1-9]\d{0,2})\.){3}(?2)" <<< "$1"; then
    if grep -P "(([1-9]\d{0,2})\.){3}(?2)" <<< "$1"; then
+
curl ipinfo.io/"$1"
curl ipinfo.io/"$1"
+
    else
    else
+
ipawk=($(host "$1" | awk '/address/ { print $NF }'))
ipawk=($(host "$1" | awk '/address/ { print $NF }'))
+
curl ipinfo.io/${ipawk[1]}
curl ipinfo.io/${ipawk[1]}
+
    fi
    fi
+
    echo
    echo
+
}
}</nowiki>
 
}}
 
  
 
{{Note|Bash is limited to extended regular expressions; this example uses perl regular expressions with ''grep''. [http://unix.stackexchange.com/questions/84477/forcing-bash-to-use-perl-regex-engine]}}
 
{{Note|Bash is limited to extended regular expressions; this example uses perl regular expressions with ''grep''. [http://unix.stackexchange.com/questions/84477/forcing-bash-to-use-perl-regex-engine]}}

Latest revision as of 15:22, 10 June 2018

Bash also supports functions. Add the functions to ~/.bashrc, or a separate file which is sourced from ~/.bashrc. More Bash function examples can be found in BBS#30155.

Display error codes

To set trap to intercept a non-zero return code of the last program run:

EC() {
	echo -e '\e[1;33m'code $?'\e[m\n'
}
trap EC ERR

Compile and execute a C source on the fly

The following function will compile (within the /tmp/ directory) and execute the C source argument on the fly (and the execution will be without arguments). And finally, after program terminates, will remove the compiled file.

# Compile and execute a C source on the fly
csource() {
	[[ $1 ]]    || { echo "Missing operand" >&2; return 1; }
	[[ -r $1 ]] || { printf "File %s does not exist or is not readable\n" "$1" >&2; return 1; }
	local output_path=${TMPDIR:-/tmp}/${1##*/};
	gcc "$1" -o "$output_path" && "$output_path";
	rm "$output_path";
	return 0;
}

Extract

The following function will extract a wide range of compressed file types. and use it with the syntax extract <file1> <file2> ...

extract() {
    local c e i

    (($#)) || return

    for i; do
        c=''
        e=1

        if [[ ! -r $i ]]; then
            echo "$0: file is unreadable: \`$i'" >&2
            continue
        fi

        case $i in
            *.t@(gz|lz|xz|b@(2|z?(2))|a@(z|r?(.@(Z|bz?(2)|gz|lzma|xz)))))
                   c=(bsdtar xvf);;
            *.7z)  c=(7z x);;
            *.Z)   c=(uncompress);;
            *.bz2) c=(bunzip2);;
            *.exe) c=(cabextract);;
            *.gz)  c=(gunzip);;
            *.rar) c=(unrar x);;
            *.xz)  c=(unxz);;
            *.zip) c=(unzip);;
            *)     echo "$0: unrecognized file extension: \`$i'" >&2
                   continue;;
        esac

        command "${c[@]}" "$i"
        ((e = e || $?))
    done
    return "$e"
}
Note: Make sure extglob is enabled: shopt -s extglob, by adding it to the ~/.bashrc (see gregswiki:glob#Options_which_change_globbing_behavior).

Another way to do this is to install a specialized package, see Archiving and compression tools#Convenience tools.

cd and ls in one

Very often changing to a directory is followed by the ls command to list its contents. Therefore it is helpful to have a second function doing both at once. In this example we will name it cl (change list) and show an error message if the specified directory does not exist.

cl() {
	local dir="$1"
	local dir="${dir:=$HOME}"
	if [[ -d "$dir" ]]; then
		cd "$dir" >/dev/null; ls
	else
		echo "bash: cl: $dir: Directory not found"
	fi
}

Of course the ls command can be altered to fit your needs, for example ls -hall --color=auto.

Simple note taker

note () {
    # if file doesn't exist, create it
    if [[ ! -f $HOME/.notes ]]; then
        touch "$HOME/.notes"
    fi

    if ! (($#)); then
        # no arguments, print file
        cat "$HOME/.notes"
    elif [[ "$1" == "-c" ]]; then
        # clear file
        printf "%s" > "$HOME/.notes"
    else
        # add all arguments to file
        printf "%s\n" "$*" >> "$HOME/.notes"
    fi
}

Simple task utility

Inspired by #Simple note taker

todo() {
    if [[ ! -f $HOME/.todo ]]; then
        touch "$HOME/.todo"
    fi

    if ! (($#)); then
        cat "$HOME/.todo"
    elif [[ "$1" == "-l" ]]; then
        nl -b a "$HOME/.todo"
    elif [[ "$1" == "-c" ]]; then
        > $HOME/.todo
    elif [[ "$1" == "-r" ]]; then
        nl -b a "$HOME/.todo"
        eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo
        read -p "Type a number to remove: " number
        sed -i ${number}d $HOME/.todo "$HOME/.todo"
    else
        printf "%s\n" "$*" >> "$HOME/.todo"
    fi
}

Calculator

calc() {
    echo "scale=3;$@" | bc -l
}

Kingbash

Kingbash - menu driven auto-completion (see BBS#101010).

Install kingbash-gb-gitAUR from the AUR, then insert the following into your ~/.bashrc:

function kingbash.fn() {
    echo -n "KingBash> $READLINE_LINE" #Where "KingBash> " looks best if it resembles your PS1, at least in length.
    OUTPUT=$(/usr/bin/kingbash "$(compgen -ab -A function)")
    READLINE_POINT=$(echo "$OUTPUT" | tail -n 1)
    READLINE_LINE=$(echo "$OUTPUT" | head -n -1)
    echo -ne "\r\e[2K"
}
bind -x '"\t":kingbash.fn'

IP info

Detailed information on an IP address or hostname in bash via http://ipinfo.io:

ipif() { 
    if grep -P "(([1-9]\d{0,2})\.){3}(?2)" <<< "$1"; then
	 curl ipinfo.io/"$1"
    else
	ipawk=($(host "$1" | awk '/address/ { print $NF }'))
	curl ipinfo.io/${ipawk[1]}
    fi
    echo
}
Note: Bash is limited to extended regular expressions; this example uses perl regular expressions with grep. [1]