Echo Control C character
Asked Answered
H

6

21

I need to grep the output of a third party program. This program dumps out data but does not terminate without pressing ^c to terminate it.

I am currently searching and killing it using its pid. However, I was wondering however if it were possible to echo the control C character. Pseudo code would look like

echo ^c | ./program_that_does_not_terminate

I am able to do something like this in DOS, so there must be a way in linux.

C:\>echo y | del C:\tmp\*
C:\tmp\*, Are you sure (Y/N)? y
C:\>
Hypanthium answered 1/6, 2011 at 4:35 Comment(0)
E
28

No, piping a CTRL-C character into your process won't work, because a CTRL-C keystroke is captured by the terminal and translated into a kill signal sent to the process.

The correct character code (in ASCII) for CTRL-C is code number 3 but, if you echo that to your program, it will simply receive the character from its standard input. It won't cause the process to terminate.

If you wanted to ease the task of finding and killing the process, you could use something like:

./program_that_does_not_terminate &
pid=$!
sleep 20
kill ${pid}

$! will give you the process ID for the last started background process.

Exhume answered 1/6, 2011 at 4:36 Comment(3)
Or kill -s SIGINT if you want to send it Ctrl-C.Somerset
upvoting. This really seems to be the only possible solutionHypanthium
killing $! is ok. But how he will grep the output from a command what running in the bg? becasue yes | wc & , will return the pid of wc and not the forever yes command, (yes | wc ) & will return the bash pid, again not the pid of the yes. So, IMHO the only way is send both command into BG, and kill the yes by its name from the ps command. Or here is more easy way grepping (or counting) the output of the command what run forever and need break it?Interdigitate
O
19

In Bash, a ^C can be passed as an argument on the command-line (and thus passed to echo for echoing) by writing $'\cc'. Thus, the desired command is:

echo $'\cc' | ./program_that_does_not_terminate
Omen answered 1/6, 2011 at 4:37 Comment(4)
While that will send the correct key sequence to the program, it won't cause the program to exit. Signal handling like CTRL-C is done by the terminal rather than the program.Exhume
SIGINT (CTRL-C) is handled by terminal driver + kernel. So sending chr(\003) (CTRL-C in ascii) DOES not terminate anything. Imagine, how much CTRL-C is in one binary program, like "ls" or soo. Anyway, when you do cat /bin/ls | strings, no command get terminated... ;)Interdigitate
is there some way to send '^]' to telnet?Renovate
used this but with -n as echo will append a newline. eg. echo -n $'\cc' >/dev/ttyUSB0Curvet
N
2

Try the following:

expect -c "send \003;"
Naga answered 13/4, 2016 at 8:57 Comment(4)
While this code may answer the question, providing additional context regarding why and/or how it answers the question would significantly improve its long-term value. Please edit your answer to add some explanation.Makassar
This is definitively the answer. I needed to send a "CTRL+C" instruction to interrupt boot loading on a device. Sending expect -c "send \003;" > /dev/ttyUSB0 did the trick. Thanks!Pulling
What does \003 mean? What if I need some other key combination? How do I find which code to use?Igloo
@SidneydeMoraes I had the same question, then found this page: windmill.co.uk/ascii-control-codes.html; it has a hex code to key combination mapping, hopefully this is helpfulRashad
Z
1

I think, you will need something more complex here. If you want to capture the output of the program you can't send the kill signal immediately to the program. Compared to your example above, the del command waits for input, while CTRL+C is no direct input but a kill signal.

I would suggest a solution where you identify if all output is captured and send the kill signal afterwards. Hoever, the point in time when all output can only be determined by you.

Zaremski answered 1/6, 2011 at 4:43 Comment(0)
Q
0

As @paxdiablo said, CTRL-C keystroke is captured by the terminal and translated into a kill signal sent to the process. So if your process is attached to a terminal, you can send $'\cc' provided by @jwodder to that terminal, letting the terminal send actual kill signal to the process.

Step:

1.Compile the C file in Execute a command in another terminal via /dev/pts

2.sudo ./a.out -n /dev/pts/0 $'\cc' # change /dev/pts/0 to the tty your process attached to

Quiddity answered 1/7, 2019 at 3:39 Comment(0)
H
0

Using the following tables you should be able to output any control sequecene you wish for example echo -e '\x03' or printf '%b\x03' you can see is Ctrl+C and so on. (Injosoft AB.,2005)(Windmill Software.,2024)(Albing, C. et al, 2024)

Albing, C., Vossen, J. P., & Newham, C. (2024). A.11. echo Options and Escape Sequences - bash Cookbook [Book]. Retrieved February 15, 2024, from https://www.oreilly.com/library/view/bash-cookbook/059652

Injosoft AB. (2005). ASCII table - Table of ASCII codes, characters and symbols. Retrieved February 15, 2024, from https://www.ascii-code.com/

Windmill Software. (2024). Control codes - converting to ASCII, hex or decimal. Retrieved February 15, 2024, from https://www.windmill.co.uk/ascii-control-codes.html
Hock answered 14/2 at 19:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.