My tests and explanation about clipboards and xclip usage.
Introduction
From man xclip:
-i, -in
read text into X selection from standard input or files (default)
-o, -out
print the selection to standard out (generally for piping to a file or
program)
...
-t, -target
specify a particular data format using the given target atom. With -o
the special target atom name "TARGETS" can be used to get a list of
valid target atoms for this selection. For more information about tar‐
get atoms refer to ICCCM section 2.6.2
...
-selection
specify which X selection to use, options are "primary" to use XA_PRI‐
MARY (default), "secondary" for XA_SECONDARY or "clipboard" for
XA_CLIPBOARD
There are 3 differents clipboards:
primary for XA_PRIMARY, they could be abbreviated p, this clipboard used for storing information copied by Ctrl+C or Ctrl+X.
seconday for XA_SECONDARY, they could be abbreviated s (I'm not sure where this clipboard is used) and
clipboard for XA_CLIPBOARD which is used immediately when some text are selected (by left mouse button or any VIM or EMACS trapping method.) and could be pasted by simple click on middle mouse button.
Dump ALL clipboard informations
Well, for showing what are precisely stored, I wrote this:
clipDump () {
local tgts tgt clip errstr
local -i errfd
mapfile -t tgts < <(xclip -selection ${1:-primary} -o -t TARGETS)
for tgt in "${tgts[@]}"; do
exec {errfd}<> <(:)
clip="$(xclip -selection ${1:-primary} -t $tgt -o 2>&$errfd)"
IFS= read -ru $errfd -t .01 errstr
exec {errfd}>&-
printf '%-30s: %q\e[31m%q\e[0m\n' $'\e[44;30m'"$tgt"$'\e[0m' "$clip" "$errstr"
done
}
Note: I use printf %q in order to prevent binary data to polute output. This will translate newlines into \n and so on.
Immediately after pasted this, I'v tried:
clipDump c
TIMESTAMP : 1695759029''
TARGETS : $'TIMESTAMP\nTARGETS\nMULTIPLE\nSAVE_TARGETS\ntext/html\ntex
t/_moz_htmlcontext\ntext/_moz_htmlinfo\nUTF8_STRING\nCOMPOUND_TEXT\nTEXT\nSTRING
\ntext/plain;charset=utf-8\ntext/plain\ntext/x-moz-url-priv'''
MULTIPLE : ''Error:\ target\ MULTIPLE\ not\ available
SAVE_TARGETS : ''''
text/html : \<meta\ http-equiv=\"content-type\"\ content=\"text/html\;\
charset=utf-8\"\>\<pre\ class=\"lang-bash\ s-code-block\"\>\<code\ data-highligh
ted=\"yes\"\ class=\"hljs\ language-bash\"\>xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP
\</code\>\</pre\>''
bash: warning: command substitution: ignored null byte in input
text/_moz_htmlcontext: \<html\ itemscope=\"\"\ itemtype=\"https://schema.org/QAP
age\"\ class=\"html__responsive\ \"\ lang=\"en\"\>\<body\ class=\"question-page\
unified-theme\ theme-dark\"\>\<div\ class=\"container\"\>\<div\ id=\"content\"\
class=\"snippet-hidden\"\>\<div\ itemprop=\"mainEntity\"\ itemscope=\"\"\ itemt
ype=\"https://schema.org/Question\"\>\<div\ class=\"inner-content\ clearfix\"\>\
<div\ id=\"mainbar\"\ role=\"main\"\ aria-label=\"question\ and\ answers\"\>\<di
v\ class=\"question\ js-question\"\ data-questionid=\"79058411\"\ data-position-
on-page=\"0\"\ data-score=\"0\"\ id=\"question\"\>\<div\ class=\"post-layout\ \"
\>\<div\ class=\"postcell\ post-layout--right\"\>\<div\ class=\"s-prose\ js-post
-body\"\ itemprop=\"text\"\>\<pre\ class=\"lang-bash\ s-code-block\"\>\</pre\>\<
/div\>\</div\>\</div\>\</div\>\</div\>\</div\>\</div\>\</div\>\</div\>\</body\>\
</html\>''
bash: warning: command substitution: ignored null byte in input
text/_moz_htmlinfo: 0\,0''
UTF8_STRING : xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
COMPOUND_TEXT : xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
TEXT : xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
STRING : xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
text/plain;charset=utf-8: xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
text/plain : xclip\ -sel\ clip\ -o\ -t\ TIMESTAMP''
bash: warning: command substitution: ignored null byte in input
text/x-moz-url-priv: https://stackoverflow.com/questions/79058411/xclip-timestam
p-time-units''
But there are some errors! bash can't deal with null bytes.
Dump clipboard through od:
Replacing 1st %q by '%s'and using od -A n -t a for showing null bytes.
clipDump () {
local tgts tgt clip errstr
local -i errfd
mapfile -t tgts < <(xclip -selection ${1:-primary} -o -t TARGETS)
for tgt in "${tgts[@]}"; do
exec {errfd}<> <(:)
clip="$(xclip -selection ${1:-primary} -t $tgt -o 2>&$errfd | od -t a -A n)"
IFS= read -ru $errfd -t .01 errstr
exec {errfd}>&-
printf "%-30s: '%s'\e[31m%q\e[0m\n" $'\e[44;30m'"$tgt"$'\e[0m' "$clip" "$errstr"
done
}
clipDump c
TIMESTAMP : ' 1 6 9 5 7 5 9 0 2 9 nl'''
TARGETS : ' T I M E S T A M P nl T A R G E T
S nl M U L T I P L E nl S A V E _
T A R G E T S nl t e x t / h t m
l nl t e x t / _ m o z _ h t m l
c o n t e x t nl t e x t / _ m o
z _ h t m l i n f o nl U T F 8 _
S T R I N G nl C O M P O U N D _
T E X T nl T E X T nl S T R I N G
nl t e x t / p l a i n ; c h a r
s e t = u t f - 8 nl t e x t / p
l a i n nl t e x t / x - m o z -
u r l - p r i v nl'''
MULTIPLE : ''Error:\ target\ MULTIPLE\ not\ available
SAVE_TARGETS : ''''
text/html : ' < m e t a sp h t t p - e q u i v
= " c o n t e n t - t y p e " sp
c o n t e n t = " t e x t / h t
m l ; sp c h a r s e t = u t f -
8 " > < p r e sp c l a s s = " l
a n g - b a s h sp s - c o d e -
b l o c k " > < c o d e sp d a t
a - h i g h l i g h t e d = " y
e s " sp c l a s s = " h l j s sp
l a n g u a g e - b a s h " > x
c l i p sp - s e l sp c l i p sp -
o sp - t sp T I M E S T A M P < /
c o d e > < / p r e >'''
text/_moz_htmlcontext: ' < nul h nul t nul m nul l nul sp nul i nul t nul
e nul m nul s nul c nul o nul p nul e nul = nul
" nul " nul sp nul i nul t nul e nul m nul t nul
y nul p nul e nul = nul " nul h nul t nul t nul
p nul s nul : nul / nul / nul s nul c nul h nul
e nul m nul a nul . nul o nul r nul g nul / nul
Q nul A nul P nul a nul g nul e nul " nul sp nul
c nul l nul a nul s nul s nul = nul " nul h nul
t nul m nul l nul _ nul _ nul r nul e nul s nul
p nul o nul n nul s nul i nul v nul e nul sp nul
" nul sp nul l nul a nul n nul g nul = nul " nul
e nul n nul " nul > nul < nul b nul o nul d nul
y nul sp nul c nul l nul a nul s nul s nul = nul
" nul q nul u nul e nul s nul t nul i nul o nul
n nul - nul p nul a nul g nul e nul sp nul u nul
n nul i nul f nul i nul e nul d nul - nul t nul
h nul e nul m nul e nul sp nul t nul h nul e nul
m nul e nul - nul d nul a nul r nul k nul " nul
> nul < nul d nul i nul v nul sp nul c nul l nul
a nul s nul s nul = nul " nul c nul o nul n nul
....
i nul v nul > nul < nul / nul d nul i nul v nul
> nul < nul / nul d nul i nul v nul > nul < nul
/ nul d nul i nul v nul > nul < nul / nul d nul
i nul v nul > nul < nul / nul d nul i nul v nul
> nul < nul / nul d nul i nul v nul > nul < nul
/ nul d nul i nul v nul > nul < nul / nul b nul
o nul d nul y nul > nul < nul / nul h nul t nul
m nul l nul > nul'''
text/_moz_htmlinfo: ' 0 nul , nul 0 nul'''
UTF8_STRING : ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
COMPOUND_TEXT : ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
TEXT : ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
STRING : ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
text/plain;charset=utf-8: ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
text/plain : ' x c l i p sp - s e l sp c l i p sp
- o sp - t sp T I M E S T A M P'''
text/x-moz-url-priv: ' h nul t nul t nul p nul s nul : nul / nul / nul
s nul t nul a nul c nul k nul o nul v nul e nul
r nul f nul l nul o nul w nul . nul c nul o nul
m nul / nul q nul u nul e nul s nul t nul i nul
o nul n nul s nul / nul 7 nul 9 nul 0 nul 5 nul
8 nul 4 nul 1 nul 1 nul / nul x nul c nul l nul
i nul p nul - nul t nul i nul m nul e nul s nul
t nul a nul m nul p nul - nul t nul i nul m nul
e nul - nul u nul n nul i nul t nul s nul'''
Null bytes!
Well, then we can see: TARGETS text/_moz_htmlcontext and text/x-moz-url-priv output's are encoded in UTF-16!
For this you could use tr -d \\0 but you'd better use a conversion tool:
clip="$(xclip -sel c -o -t text/x-moz-url-priv | iconv -f utf16)"
echo "$clip"
or
clip="$(xclip -sel c -o -t text/x-moz-url-priv | recode -f u7..u8)"
echo "$clip"
https://stackoverflow.com/questions/749544/pipe-to-from-the-clipboard-in-a-bash-script?page=2&tab=scoredesc#tab-top
Final version
For final version, I've replaced %q by %s in order to obtain a cleaner output, and added one switch: -b for binary mode, where output are reformated by od -ta -An, then newlines and exessive spaces are dropped.
clipDump() {
local _Targets _target _store _errMsg
local -i _errFD _binMode=0
[[ $1 == -b ]] && shift && _binMode=1
mapfile -t _Targets < <(xclip -selection ${1:-primary} -o -t TARGETS)
for _target in "${_Targets[@]}"; do
exec {_errFD}<> <(:)
if ((_binMode)); then
_store="$(
xclip -selection ${1:-primary} -t $_target -o 2>&$_errFD |
od -ta -An |
tr -d \\n |
sed '
s/^[[:space:]]*//;
s/[[:space:]]*$//;
s/[[:space:]]\+/ /g;
')"
else
_store="$(xclip -selection ${1:-primary} -t $_target -o 2>&$_errFD)"
fi
IFS= read -ru $_errFD -t .01 _errMsg
exec {_errFD}>&-
printf "%-30s: %s\e[31m%s\e[0m\n" \
$'\e[44;30m'"$_target"$'\e[0m' "$_store" "$_errMsg"
done
}
clipDump
TIMESTAMP : 2020839389
TARGETS : TIMESTAMP
TARGETS
MULTIPLE
text/html
text/_moz_htmlcontext
text/_moz_htmlinfo
UTF8_STRING
COMPOUND_TEXT
TEXT
STRING
text/plain;charset=utf-8
text/plain
text/x-moz-url-priv
MULTIPLE : Error: target MULTIPLE not available
text/html : <meta http-equiv="content-type" content="text/html; charset=utf-8"><pre class="lang-bash s-code-block"><code data-highlighted="yes" class="hljs language-bash">clipDump</code></pre>
bash: warning: command substitution: ignored null byte in input
text/_moz_htmlcontext: <html itemscope="" itemtype="https://schema.org/QAPage" class="html__responsive " lang="en"><body class="question-page unified-theme theme-dark"><div class="container"><div id="content" class="snippet-hidden"><div itemprop="mainEntity" itemscope="" itemtype="https://schema.org/Question"><div class="inner-content clearfix"><div id="mainbar" role="main" aria-label="question and answers"><div id="answers"><div id="answer-79059847" class="answer js-answer highlighted-post" data-answerid="79059847" data-parentid="749544" data-score="2" data-position-on-page="27" data-highest-scored="0" data-question-has-accepted-highest-score="0" itemprop="suggestedAnswer" itemscope="" itemtype="https://schema.org/Answer"><div class="post-layout"><div class="answercell post-layout--right"><div class="inline-editor" style=""><form class="inline-post" action="/posts/79059847/edit-submit/29257632-6d0e-4ec5-a1f3-a71b7f11b79d" method="post" data-post-params="{"is_suggested_edit":false,"post_type":2,"owner":1,"PostId":79059847}"><div id="post-editor-79059847" class="post-editor js-post-editor d-flex fd-column g4"><div id="wmd-preview-79059847" class="s-prose mb16 wmd-preview js-wmd-preview"><pre class="lang-bash s-code-block"></pre></div></div></form></div></div></div></div></div></div></div></div></div></div></body></html>
bash: warning: command substitution: ignored null byte in input
text/_moz_htmlinfo: 0,0
UTF8_STRING : clipDump
COMPOUND_TEXT : clipDump
TEXT : clipDump
STRING : clipDump
text/plain;charset=utf-8: clipDump
text/plain : clipDump
bash: warning: command substitution: ignored null byte in input
text/x-moz-url-priv: https://stackoverflow.com/questions/749544/pipe-to-from-the-clipboard-in-a-bash-script/79059847#79059847
clipDump -b
TIMESTAMP : 2 0 2 0 8 9 8 7 4 8 nl
TARGETS : T I M E S T A M P nl T A R G E T S nl M U L T I P L E nl t e x t / h t m l nl t e x t / _ m o z _ h t m l c o n t e x t nl t e x t / _ m o z _ h t m l i n f o nl U T F 8 _ S T R I N G nl C O M P O U N D _ T E X T nl T E X T nl S T R I N G nl t e x t / p l a i n ; c h a r s e t = u t f - 8 nl t e x t / p l a i n nl t e x t / x - m o z - u r l - p r i v nl
MULTIPLE : Error: target MULTIPLE not available
text/html : < m e t a sp h t t p - e q u i v = " c o n t e n t - t y p e " sp c o n t e n t = " t e x t / h t m l ; sp c h a r s e t = u t f - 8 " > < p r e sp c l a s s = " l a n g - b a s h sp s - c o d e - b l o c k " > < c o d e sp d a t a - h i g h l i g h t e d = " y e s " sp c l a s s = " h l j s sp l a n g u a g e - b a s h " > c l i p D u m p sp - b < / c o d e > < / p r e >
text/_moz_htmlcontext: < nul h nul t nul m nul l nul sp nul i nul t nul e nul m nul s nul c nul o nul p nul e nul = nul " nul " nul sp nul i nul t nul e nul m nul t nul y nul p nul e nul = nul " nul h nul t nul t nul p nul s nul : nul / nul / nul s nul c nul h nul e nul m nul a nul . nul o nul r nul g nul / nul Q nul A nul P ... = nul " nul l nul a nul n nul g nul - nul b nul a nul s nul h nul sp nul s nul - nul c nul o nul d nul e nul - nul b nul l nul o nul c nul k nul " nul > nul < nul / nul p nul r nul e nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul f nul o nul r nul m nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul d nul i nul v nul > nul < nul / nul b nul o nul d nul y nul > nul < nul / nul h nul t nul m nul l nul > nul
text/_moz_htmlinfo: 0 nul , nul 0 nul
UTF8_STRING : c l i p D u m p sp - b
COMPOUND_TEXT : c l i p D u m p sp - b
TEXT : c l i p D u m p sp - b
STRING : c l i p D u m p sp - b
text/plain;charset=utf-8: c l i p D u m p sp - b
text/plain : c l i p D u m p sp - b
text/x-moz-url-priv: h nul t nul t nul p nul s nul : nul / nul / nul s nul t nul a nul c nul k nul o nul v nul e nul r nul f nul l nul o nul w nul . nul c nul o nul m nul / nul q nul u nul e nul s nul t nul i nul o nul n nul s nul / nul 7 nul 4 nul 9 nul 5 nul 4 nul 4 nul / nul p nul i nul p nul e nul - nul t nul o nul - nul f nul r nul o nul m nul - nul t nul h nul e nul - nul c nul l nul i nul p nul b nul o nul a nul r nul d nul - nul i nul n nul - nul a nul - nul b nul a nul s nul h nul - nul s nul c nul r nul i nul p nul t nul / nul 7 nul 9 nul 0 nul 5 nul 9 nul 8 nul 4 nul 7 nul # nul 7 nul 9 nul 0 nul 5 nul 9 nul 8 nul 4 nul 7 nul
Sending datas to clipboard
For posting on this site, for sample, I often use something like:
COLUMNS=88 man -Len -Pcat xclip |
sed '/^[[:space:]]*\(-[iot]\|-sel\)/,/^ *$/s/^/> /p;d' |
xclip
Then I could simply paste:
-i, -in
read text into X selection from standard input or files (default)
-o, -out
print the selection to standard out (generally for piping to a file or
program)
-t, -target
specify a particular data format using the given target atom. With -o
the special target atom name "TARGETS" can be used to get a list of
valid target atoms for this selection. For more information about tar‐
get atoms refer to ICCCM section 2.6.2
-selection
specify which X selection to use, options are "primary" to use XA_PRI‐
MARY (default), "secondary" for XA_SECONDARY or "clipboard" for
XA_CLIPBOARD
( There is no need to precise: xclip -i -sel p. ;-)