Caveat: This answer literally does exactly what is requested. However, keyboard typed terminal input must quote the ctrl-D and send it ( ctrl+v ctrl+d Enter ) so the script can "see" it since bash
keyboard processing will "trap & grab" and process the ctrl-D without propagation otherwise.
Consequently bash
preprocesses, with some predefined function, every keyboard control code:
( ^@ ^A ... ^Z ^[ ^\ ^] ^^ ^_ ^?
where ^
means hold ctrl then type the character)
so that the ^V
predefined function "quotes" and thus escapes other ctrl'dkey
functionality, so the key
character code can be propagated.
aside curio:
ctrl@ aka ctrlshift2 over the decades usefully creates a null
character code
ctrl[ aka Esc also useful when Esc
is missing or broken
Cut to the chase:
echo ^v^d>ctrl-D.txt
gedit your-script.sh ctrl-D.txt
Highlight the ctrl-D character code (it is the only) character in ctrl-D.txt
and copy and paste it to replace the bye
in your-script.sh
.
Note bene: the embedded code is exactly 0x04
preceded by white space and postceded by a )
.
The script will now terminate on receiving a ctrl-D, but here's the rub. If bash
is the shell it will not receive it because bash
will have already processed it. AFAIK there does not exist a unix / linux shell which does not behave like this so it is necessary to quote the ctrl-D so the shell does not grab it. (Ctrl-D was one of the early primitives "used to end text input or to exit a Unix shell".)
To quote the ctrl-D and pass it on through the shell to the script type ctrl+v ctrl+d Enter in bash
. YMMV (your mileage may vary) and some other quoting method may be available in other shells.
The long answer:
To embed a control code in a shell script quote it using ctrl+v.
It is understood that the ^
letter sequences in the coding examples are not to be typed literally with an ^
, but as a ctrl and letter combination.
Type ctrl+v ctrl+d contiguously.
(for expediency hold the ctrl and type v then d)
Thus typing echo
ctrl+vd
linuxuser@ubuntu:~$ echo ^v^d
get this:
____
|00|
|04|
but as a single "code revealed" character, not the 12 _
's |
's #
's used here to represent the result.
To embed a control code like ^D
in a file such as bye
use
echo
ctrl+vd >bye
Thus:
linuxuser@ubuntu:~$ echo now you can see -^v^d- via cat -v >bye
linuxuser@ubuntu:~$ cat -v bye
now you can see -^D- via cat -v
reveals the ctrld character by the two characters, an ^
and a D
.
For the curious:
Note that quoting the quote to quote a code has been useful.
Thus (hold) ctrl (type) vvvz (and then release ctrl) will create a ^V^Z
sequence in bash
.
A poignant point worth noting is that files may contain arbitrary bytes. Ergo control codes per se do not "mean anything". It is on exposure to interpretation, like bash scripts, that various sequences might have meaning as control codes. It is very useful in bash
that ctrlv can "disable" bash
control code interpretation by its quoting mechanism. Most particularly, quoting is useful within files themselves that are to be interpreted by bash
as scripts.
Coda:
linuxuser@ubuntu:~$ echo -e "echo 'ctrl-D^v^j -^v^d-' >bye \ncat -v bye" >doit.sh
linuxuser@ubuntu:~$ ./doit.sh
prints
ctrl-D
-^D-
tested with
linuxuser@ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic