Convert snipplets to Markdown

This commit is contained in:
flokoe 2023-07-05 11:33:45 +02:00
parent 82096dc0ff
commit 22386b0460
14 changed files with 815 additions and 0 deletions

View File

@ -0,0 +1,103 @@
# Add Color to your scripts
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags : terminal, color
LastUpdate_dt : 2013-03-23 Contributors : Frank Lazzarini, Dan Douglas
type : snipplet
------------------------------------------------------------------------
Make your scripts output more readable using bash colors. Simply add
these variables to your script, and you will be able to echo in color.
(I haven\'t added all the colors available, just some basics)
# Colors
ESC_SEQ="\x1b["
COL_RESET=$ESC_SEQ"39;49;00m"
COL_RED=$ESC_SEQ"31;01m"
COL_GREEN=$ESC_SEQ"32;01m"
COL_YELLOW=$ESC_SEQ"33;01m"
COL_BLUE=$ESC_SEQ"34;01m"
COL_MAGENTA=$ESC_SEQ"35;01m"
COL_CYAN=$ESC_SEQ"36;01m"
Now if you want to output some text in color use *echo -e* instead of
just echo. And always remember to use the *\$COL_RESET* variable to
reset the color changes in bash. Like so \....
echo -e "$COL_RED This is red $COL_RESET"
echo -e "$COL_BLUE This is blue $COL_RESET"
echo -e "$COL_YELLOW This is yellow $COL_RESET"
But also see the notes in [the article about using
terminalcodes](/scripting/terminalcodes) about generating codes and
hardwiring codes.
This snipplet sets up associative arrays for basic color codes using
`tput` for Bash, ksh93 or zsh. You can pass it variable names to
correspond with a collection of codes. There\'s a `main` function with
example usage.
``` bash
#!/usr/bin/env bash
${ZSH_VERSION+false} || emulate ksh
${BASH_VERSION+shopt -s lastpipe extglob}
# colorSet [ --setaf | --setab | --misc ] var
# Assigns the selected set of escape mappings to the given associative array names.
function colorSet {
typeset -a clrs msc
typeset x
clrs=(black red green orange blue magenta cyan grey darkgrey ltred ltgreen yellow ltblue ltmagenta ltcyan white)
msc=(sgr0 bold dim smul blink rev invis)
while ! ${2:+false}; do
${KSH_VERSION:+eval typeset -n "$2"=\$2}
case ${1#--} in
setaf|setab)
for x in "${!clrs[@]}"; do
eval "$2"'[${clrs[x]}]=$(tput "${1#--}" "$x")'
done
;;
misc)
for x in "${msc[@]}"; do
eval "$2"'[$x]=$(tput "$x")'
done
;;
*)
return 1
esac
shift 2
done
}
# Example code
function main {
typeset -A fgColors bgColors miscEscapes
if colorSet --setaf fgColors --setab bgColors --misc miscEscapes; then
if ! ${1:+${fgColors[$1]:+false}}; then
printf '%s%s%s\n' "${fgColors[$1]}" "this text is ${1}" "${miscEscapes[sgr0]}" >&3
else
printf '%s, %s\n' "${1:-Empty}" 'no such color.'
typeset x y
for x in fgColors bgColors miscEscapes; do
typeset -a keys
eval 'keys=("${!'"$x"'[@]}")'
printf '%s=( ' "$x"
for y in "${keys[@]}"; do
eval 'printf "[%q]=%q " "$y" "${'"$x"'[$y]}"'
done
printf ')\n'
done
return 1
fi
else
echo 'Failed setting color arrays.'
return 1
fi 3>&1 >&2
}
main "$@"
# vim: set fenc=utf-8 ff=unix ft=sh :
```

45
docs/snipplets/awkcsv.md Normal file
View File

@ -0,0 +1,45 @@
# Using `awk` to deal with CSV that uses quoted/unquoted delimiters
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags : awk, csv
LastUpdate_dt : 2010-07-31 Contributors : SiegX (IRC) type : snipplet
------------------------------------------------------------------------
CSV files are a mess, yes.
Assume you have CSV files that use the comma as delimiter and quoted
data fields that can contain the delimiter.
"first", "second", "last"
"fir,st", "second", "last"
"firtst one", "sec,ond field", "final,ly"
Simply using the comma as separator for `awk` won\'t work here, of
course.
Solution: Use the field separator `", "|^"|"$` for `awk`.
This is an OR-ed list of 3 possible separators:
-------- -----------------------------------------------
`", "` matches the area between the datafields
`^"` matches the area left of the first datafield
`"$` matches the area right of the last data field
-------- -----------------------------------------------
You can tune these delimiters if you have other needs (for example if
you don\'t have a space after the commas).
Test:
The `awk` command used for the CSV above just prints the fileds
separated by `###` to see what\'s going on:
$ awk -v FS='", "|^"|"$' '{print $2"###"$3"###"$4}' data.csv
first###second###last
fir,st###second###last
firtst one###sec,ond field###final,ly
**ATTENTION** If the CSV data changes its format every now and then (for
example it only quotes the data fields if needed, not always), then this
way will not work.

View File

@ -0,0 +1,15 @@
# Show size of a file
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: files, file size
LastUpdate_dt: 2010-07-31 Contributors: Frank Lazzarini type: snipplet
------------------------------------------------------------------------
This is a simple snippet to echo the size of a file in bytes.
#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(wc -c < "$FILENAME")
# non standard way (GNU stat): FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."

View File

@ -0,0 +1,71 @@
# Kill a background job without a message
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: kill, process
management, jobs LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
type: snipplet
------------------------------------------------------------------------
When you start background jobs from within a script (non-interactive
shell) and kill it afterwards, you will get a message from the shell
that the process was terminated.
Example:
#!/bin/bash
# example background process
sleep 300 &
# get the PID
BG_PID=$!
# kill it, hard and mercyless
kill -9 $BG_PID
echo "Yes, we killed it"
You will get something like this:
$ ./bg_kill1.sh
./bg_kill1.sh: line 11: 3413 Killed sleep 300
Yes, we killed it
This is more or less a normal message. And it can\'t be easily
redirected since it\'s the shell itself that yells this message, not the
command `kill` or something else. You would have to redirect the whole
script\'s output.
It\'s also useless to temporarily redirect `stderr` when you call the
`kill` command, since the successful termination of the job, the
termination of the `kill` command and the message from the shell may not
happen at the same time. And a blind `sleep` after the `kill` would be
just a workaround.
The solution is relatively easy: The shell spits that message because it
controls the background job, and when it terminates, the shell will tell
you whenever possible. Now you just need to tell your shell that it is
no longer responsible for that background process. This is done by the
`disown` command, which can take an internal shell job number (like
`%1`) or a process ID as argument.
#!/bin/bash
# example background process
sleep 300 &
# get the PID
BG_PID=$!
### HERE, YOU TELL THE SHELL TO NOT CARE ANY MORE ###
disown $BG_PID
###
# kill it, hard and mercyless, now without a trace
kill -9 $BG_PID
echo "Yes, we killed it"
That way, you can run and kill background processes without disturbing
messages.

View File

@ -0,0 +1,64 @@
# Get largest file
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: directory, recursive,
find, crawl LastUpdate_dt: 2013-03-23 Contributors: Dan Douglas type:
snipplet
------------------------------------------------------------------------
One basic pattern for recursive directory traversal with operations on
files at each node. This gets the largest file in each subdirectory.
Toggling some small details will make it return the smallest, or
traverse breadth-first instead of depth-first.
``` bash
#!/usr/bin/env bash
# GNU find + bash4 / ksh93v / zsh
# Get the largest file matching pattern in the given directories recursively
${ZSH_VERSION+false} || emulate ksh
${BASH_VERSION+shopt -s lastpipe extglob}
function getLargest {
typeset -A cur top || return
typeset dir x
for dir in "$2"/*/; do
[[ -d $dir ]] || return 0
getLargest "$1" "${dir%/}" || return
top[size]=-1
find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | {
while :; do
for x in cur\[{size,name}\]; do
IFS= read -rd '' "$x" || break 2
done
if (( cur[size] > top[size] )); then
top[size]=${cur[size]} top[name]=${cur[name]}
fi
done
printf '%q\n' "${dir}${top[name]}"
}
done
}
# main pattern dir [ dir ... ]
function main {
if [[ -n $1 ]]; then
typeset dir pattern=$1
shift
for dir; do
[[ -d $dir ]] || return
getLargest "$pattern" "$dir"
done
else
return 1
fi
}
main "$@"
# vim: set fenc=utf-8 ff=unix ft=sh :
```
## More examples
- <http://mywiki.wooledge.org/BashFAQ/003>
- <http://mywiki.wooledge.org/UsingFind>

View File

@ -0,0 +1,15 @@
# Pausing a script (like MSDOS pause command)
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: terminal, pause, input
LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera type: snipplet
------------------------------------------------------------------------
From the [example section of the read
command](/commands/builtin/read#examples), something that acts similar
to the MSDOS `pause` command:
pause() {
local dummy
read -s -r -p "Press any key to continue..." -n 1 dummy
}

52
docs/snipplets/prargs.md Normal file
View File

@ -0,0 +1,52 @@
# Print argument list for testing
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: debug, arguments
LastUpdate_dt: 2013-03-23 Contributors: Snappy (IRC), Dan Douglas type:
snipplet
------------------------------------------------------------------------
Sometimes you might find it useful to see how arguments passed to a
program arrive there.
Check this script (save it as script file or make a function):
printf '"%b"\n' "$0" "$@" | nl -v0 -s": "
It uses the [printf command](/commands/builtin/printf) to generate a
list of arguments, even with escape sequences interpreted. This list is
shown formatted by the nl(1) utility.
Another alternative with colorized output. If run in Bash, it
temporarily disables all debug output for itself, including the test
that determines whether to hide debug output. In ksh, tracing would have
to be enabled on the function to show debug output, so it works out to
being equivalent.
``` bash
# Bash or ksh93 debugging function for colored display of argv.
# Optionally set OFD to the desired output file descriptor.
function args {
{ BASH_XTRACEFD=3 command eval ${BASH_VERSION+"$(</dev/fd/0)"}; } <<-'EOF' 3>/dev/null
case $- in *x*)
set +x
trap 'trap RETURN; set -x' RETURN
esac
EOF
[[ ${OFD-1} == +([0-9]) ]] || return
if [[ -t ${OFD:-2} ]]; then
typeset -A clr=([green]=$(tput setaf 2) [sgr0]=$(tput sgr0))
else
typeset clr
fi
if ! ${1+false}; then
printf -- "${clr[green]}<${clr[sgr0]}%s${clr[green]}>${clr[sgr0]} " "$@"
echo
else
echo 'no args.'
fi >&"${OFD:-2}"
}
```

View File

@ -0,0 +1,135 @@
# Print a horizontal line
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: terminal, line
LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera, prince_jammys,
ccsalvesen, others type: snipplet
------------------------------------------------------------------------
The purpose of this small code collection is to show some code that
draws a horizontal line using as less external tools as possible (it\'s
not a big deal to do it with AWK or Perl, but with pure or nearly-pure
Bash it gets more interesting).
In general, you should be able to use this code to repeat any character
or character sequence.
## The simple way: Just print it
Not a miracle, just to be complete here.
``` bash
printf '%s\n' --------------------
```
## The iterative way
This one simply loops 20 times, always draws a dash, finally a newline
``` bash
for ((x = 0; x < 20; x++)); do
printf %s -
done
echo
```
## The simple printf way
This one uses the `printf` command to print an **empty** field with a
**minimum field width** of 20 characters. The text is padded with
spaces, since there is no text, you get 20 spaces. The spaces are then
converted to `-` by the `tr` command.
``` bash
printf '%20s\n' | tr ' ' -
```
whitout an external command, using the (non-POSIX) substitution
expansion and `-v` option:
``` bash
printf -v res %20s
printf '%s\n' "${res// /-}"
```
## A line across the entire width of the terminal
This is a variant of the above that uses `tput cols` to find the width
of the terminal and set that number as the minimum field witdh.
``` bash
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
```
## The more advanced printf way
This one is a bit tricky. The format for the `printf` command is `%.0s`,
which specified a field with the **maximum** length of **zero**. After
this field, `printf` is told to print a dash. You might remember that
it\'s the nature of `printf` to repeat, if the number of conversion
specifications is less than the number of given arguments. With brace
expansion `{1..20}`, 20 arguments are given (you could easily write
`1 2 3 4 ... 20`, of course!). Following happens: The **zero-length
field** plus the dash is repeated 20 times. A zero length field is,
naturally, invisible. What you see is the dash, repeated 20 times.
``` bash
# Note: you might see that as ''%.s'', which is a (less documented) shorthand for ''%.0s''
printf '%.0s-' {1..20}; echo
```
If the 20 is variable, you can use [eval](/commands/builtin/eval) to
insert the expansion (take care that using `eval` is potentially
dangerous if you evaluate external data):
``` bash
eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo
```
Or restrict the length to 1 and prefix the arguments with the desired
character.
``` bash
eval printf %.1s '-{1..'"${COLUMNS:-$(tput cols)}"\}; echo
```
You can also do it the crazy ormaaj way™ following basically the same
principle as this [string reverse
example](/commands/builtin/eval#expansion_side-effects). It completely
depends on Bash due to its brace expansion evaluation order and array
parameter parsing details. As above, the eval only inserts the COLUMNS
expansion into the expression and isn\'t involved in the rest, other
than to put the `_` value into the environment of the `_[0]` expansion.
This works well since we\'re not creating one set of arguments and then
editing or deleting them to create another as in the previous examples.
``` bash
_=- command eval printf %s '"${_[0]"{0..'"${COLUMNS:-$(tput cols)}"'}"}"'; echo
```
## The parameter expansion way
Preparing enough dashes in advance, we can then use a non-POSIX
subscript expansion:
``` bash
hr=---------------------------------------------------------------\
----------------------------------------------------------------
printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
```
A more flexible approach, and also using modal terminal line-drawing
characters instead of hyphens:
``` bash
hr() {
local start=$'\e(0' end=$'\e(B' line='qqqqqqqqqqqqqqqq'
local cols=${COLUMNS:-$(tput cols)}
while ((${#line} < cols)); do line+="$line"; done
printf '%s%s%s\n' "$start" "${line:0:cols}" "$end"
}
```
## Related articles
- [printf](/commands/builtin/printf)

123
docs/snipplets/rndstr.md Normal file
View File

@ -0,0 +1,123 @@
# Print a random string or select random elements
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: terminal, line
LastUpdate_dt: 2013-04-30 Contributors: Dan Douglas (ormaaj) type:
snipplet
------------------------------------------------------------------------
First off, here is a fast / reliable random string function for scripts
or libraries which can optionally assign directly to a variable.
``` bash
# Print or assign a random alphanumeric string of a given length.
# rndstr len [ var ]
function rndstr {
if [[ $FUNCNAME == "${FUNCNAME[1]}" ]]; then
unset -v a
printf "$@"
elif [[ $1 != +([[:digit:]]) ]]; then
return 1
elif (( $1 )); then
typeset -a a=({a..z} {A..Z} {0..9})
eval '${2:+"$FUNCNAME" -v} "${2:-printf}" -- %s "${a[RANDOM%'"${#a[@]}"']"{1..'"$1"'}"}"'
fi
}
```
This example prints 10 random positional parameters and operates on
basically the same principle as the `rndstr` function above.
~ $ ( set -- foo bar baz bork; printf '%s ' "${!_[_=RANDOM%$#+1,0]"{0..10}"}"; echo )
bork bar baz baz foo baz baz baz baz baz bork
\<div hide\> This has some interesting option parsing concepts, but is
overly complex. This is a good example of working too hard to avoid an
eval for no benefit and some performance penalty. :/
``` bash
# Print or assign a random alphanumeric string of a given length.
# rndstr [ -v var ] len
# Bash-only
rndstr()
if [[ $FUNCNAME == "${FUNCNAME[1]}" ]]; then
# On recursion, this branch unsets the outer scope's locals and assigns the result.
unset -v a b
printf -v "$1" %s "${@:2}"
elif ! { [[ $1 == -v ]] && shift; }; [[ $?+1 -ne $# || ${!#} != +([[:digit:]]) || ( $? -gt 0 && -z $1 ) ]]; then
# This branch does input validation, strips -v, and guarantees we're left with either 1 or 2 args.
return 1
elif (( ! ${!#} )); then
# If a zero-length string is requested, return success.
return
else
# This line generates the string and assigns it to "b".
local -a a=({a..z} {A..Z} {0..9}) 'b=("${a[RANDOM%'"${#a[@]}"']"{1..'"${!#}"'}"}")'
if (( $# == 2 )); then
# If -v, then pass a variable name and value to assign and recurse once.
"$FUNCNAME" "$1" "${b[@]}"
else
# If no -v, write to stdout.
printf %s "${b[@]}"
fi
fi
```
\</div\>
The remaining examples don\'t use quite the same tricks, which will
hopefully be explained elsewhere eventually. See
[unset](commands/builtin/unset#scope) for why doing assignments in this
way works well.
This next example is a variation on
[print_horizontal_line](/snipplets/print_horizontal_line). We\'re using
the printf field width specifier to truncate the values of a
`sequence expansion` to one character.
``` bash
a=({a..z} {A..Z} {0..9})
printf '%.1s' "${a[RANDOM%${#a[@]}]}"{0..9} $'\n'
```
The extra detail that makes this work is to notice that in Bash, [brace
expansion](syntax/expansion/brace) is usually the very first type of
expansion to be processed, always before parameter expansion. Bash is
unique in this respect \-- all other shells with a brace expansion
feature perform it almost last, just before pathname expansion. First
the sequence expansion generates ten parameters, then the parameters are
expanded left-to-right causing the [arithmetic](/syntax/arith_expr) for
each to be evaluated individually, resulting in independent selection of
random element of `a`. To get ten of the same element, put the array
selection inside the format string where it will only be evaluated once,
just like the dashed-line trick:
``` bash
printf "%.s${a[RANDOM%${#a[@]}]}" {0..9}
```
Selecting random elements whose lengths are not fixed is harder.
``` bash
a=(one two three four five six seven eight nine ten)
printf '%.*s ' $(printf '%s ' "${#a[x=RANDOM%${#a[@]}]} ${a[x]}"{1..10})
```
This generates each parameter and it\'s length in pairs. The \'\*\'
modifier instructs printf to use the value preceding each parameter as
the field width. Note the space between the parameters. This example
unfortunately relies upon the unquoted command substitution to perform
unsafe wordsplitting so that the outer printf gets each argument. Values
in the array can\'t contain characters in IFS, or anything that might be
interpreted as a pattern without using `set -f`.
Lastly, empty brace expansions can be used which don\'t generate any
output that would need to be filtered. The disadvantage of course is
that you must construct the brace expansion syntax to add up to the
number of arguments to be generated, where the most optimal solution is
its set of prime factors.
``` bash
a=(one two three)
echo "${a[RANDOM%${#a[@]}]}"{,}{,,,,}
```

View File

@ -0,0 +1,24 @@
# Save and restore terminal/screen content
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: terminal, restore
screen LastUpdate_dt: 2010-07-31 Contributors: Greg Wooledge type:
snipplet
------------------------------------------------------------------------
This cool hack uses the terminal capabilities (see `terminfo(5)` manual)
**smcup** and **rmcup** to save and restore the terminal content.
For sure, you've already seen those programs that restore the terminal
contents after they did their work (like `vim`).
# save, clear screen
tput smcup
clear
# example "application" follows...
read -n1 -p "Press any key to continue..."
# example "application" ends here
# restore
tput rmcup

View File

@ -0,0 +1,24 @@
# Fetching SSH hostkeys without interaction
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: ssh, ssh-keys
LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
------------------------------------------------------------------------
Applies at least to `openssh`.
To get the hostkeys for a server, and write them to `known_hosts`-file
(to avoid that yes/no query when the key isn\'t known), you can do:
ssh-keyscan -t rsa foo foo.example.com 1.2.3.4 >> ~/.ssh/known_host
This example queries the hostkeys for the very same machine, but under 3
different \"names\" (hostname, FQDN, IP) and redirects the output to the
`known_hosts`-file.
[**Notes:**]{.underline}
- if done blindly, the `known_host`-file may grow very large. It might
be wise to check for key existance first
- if multiple keys for the same host exist in `known_hosts`, the first
one is taken (which might be an old or wrong one)

View File

@ -0,0 +1,17 @@
# Run some bash commands with SSH remotely using local variables
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: ssh, variables
LastUpdate_dt: 2010-07-31 Contributors: cweiss type: snipplet
------------------------------------------------------------------------
In this example, we want to make sure a certain file exists on the
remote server:
file=/tmp/file.log
ssh ${options} ${login} "if [ ! -e '$file' ] ; then touch '$file' ; fi"
Notice the command is surrounded by double quotes, and the \$file
variable is surrounded by single quotes. That has the effect to be
wordsplit-proof in the local shell (due to the double-quotes) and in the
remote shell (due to the single-quotes).

View File

@ -0,0 +1,93 @@
# Generate code with own arguments properly quoted
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: arguments, quoting,
escaping, wrapper LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
type: snipplet
------------------------------------------------------------------------
Keywords: arguments,escape,quote,wrapper,generate
-------------- -----------------------------------------
Contributor: self
There are situations where Bash code needs to generate Bash code. A
script that writes out another script the user or cron may start, for
example.
The general issue is easy, just write out text to the file.
A specific detail of it is tricky: If the generated script needs to call
a command using the arguments the first original script got, you have
problem in writing out the correct code.
I.e. if you run your generator script like
./myscript "give me 'some' water"
then this script should generate code that looks like
echo give me 'some' water"
you need correct escapes or quotes to not generate shell special
characters out of normal text (like embedded dollar signs `$`).
**[Solution:]{.underline}**
A loop over the own arguments that writes out properly quoted/escaped
code to the generated script file
There are two (maybe more) easy options:
- writing out singlequoted strings and handle the embedded
singlequotes
- the [printf command](/commands/builtin/printf) knows the `%q` format
specification, which will print a string (like `%s` does), but with
all shell special characters escaped
## Using singlequoted string
#!/bin/bash
# first option:
# generate singlequoted strings out of your own arguments and handle embedded singlequotes
# here to call 'echo' in the generated script
{
printf "#!/bin/bash\n\n"
printf "echo "
for arg; do
arg=${arg/\'/\'\\\'\'}
printf "'%s' " "${arg}"
done
printf "\n"
} >s2
The generated script will look like:
#!/bin/bash
echo 'fir$t' 'seco "ond"' 'thir'\''d'
## Using printf
The second method is easier, though more or less Bash-only (due to the
`%q` in printf):
#!/bin/bash
{
printf "#!/bin/bash\n\n"
printf "echo "
for arg; do
printf '%q ' "$arg"
done
printf "\n"
} >s2
The generated script will look like:
#!/bin/bash
echo fir\$t seco\ \"ond\" thir\'d

34
docs/snipplets/xclip.md Normal file
View File

@ -0,0 +1,34 @@
# X-Clipboard on Commandline
\-\-\-- dataentry snipplet \-\-\-- snipplet_tags: clipboard, x11, xclip,
readline LastUpdate_dt: 2010-07-31 Contributors: Josh Triplett type:
snipplet
------------------------------------------------------------------------
# Make Control-v paste, if in X and if xclip available - Josh Triplett
if [ -n "$DISPLAY" ] && [ -x /usr/bin/xclip ] ; then
# Work around a bash bug: \C-@ does not work in a key binding
bind '"\C-x\C-m": set-mark'
# The '#' characters ensure that kill commands have text to work on; if
# not, this binding would malfunction at the start or end of a line.
bind 'Control-v: "#\C-b\C-k#\C-x\C-?\"$(xclip -o -selection c)\"\e\C-e\C-x\C-m\C-a\C-y\C-?\C-e\C-y\ey\C-x\C-x\C-d"'
fi
The behaviour is a bit tricky to explain:
- kill text after the cursor
- since the kill command **wants** text, it blindly adds a fake
text \"#\" here
- kill text before the cursor
- since the kill command **wants** text, it blindly adds a fake
text \"#\" here, too
- write out `"$(xclip -o -selection c)"`
- run Control-Meta-e (shell-expand-line) to expand the
`"$(xclip -o -selection c)"`
- yank the previously killed text back where it belongs
Of course you can use any other command, you\'re not limited to `xclip`
here.
Note: C-@ as well as M-SPC both works and set the mark for me \-- pgas