Re: /bin/echo -- $var
echo is defunct by definition. The preferred way is printf %s\\n "data" which is much more stable against such "attacks"! Also it is far more stable to be used for multiline output: printf %s\\n "line 1" line\ 2 'line 3' "line 5 and line 6" and no, it shouldn't. echo should not be used but must not be changed. On 14/08/2019 14:01, Harald Dunkel wrote: > Hi folks, > > I just learned by accident that > > var="-n" > /bin/echo -- $var > > actually prints > > -- -n > > Shouldn't it be just > > -n > ? > > Other tools in coreutils use '--' to indicate "stop parsing for > command line flags", e.g. touch, ls and rm: > > % /bin/touch -- -l > % /bin/ls -- -l > -l > % /bin/rm -- -l > % /bin/rm -- -l > /bin/rm: cannot remove '-l': No such file or directory > > Some common style would be nice here. > > > Regards > Harri >
Re: Feature request about "Tail -f": Gentle exit (not using CTRL+C)
Hi Brian, you actually have many more options to leave a tail -f. Typing CTRL+C in a terminal that runs a process means to send SIGINT to it (see signal(7)). I could not find the exact documentation about this process, but the behavuiour of such key sequences in terminals is controlled by the terminal attributes (see termios(3)): ISIG When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal. and VINTR (003, ETX, Ctrl-C, or also 0177, DEL, rubout) Interrupt character (INTR). Send a SIGINT signal. Recognized when ISIG is set, and then not passed as input. and VQUIT (034, FS, Ctrl-\) Quit character (QUIT). Send SIGQUIT signal. Recognized when ISIG is set, and then not passed as input. So it seems that the SIGINT signal in an interactive shell quits the current input pipeline, while SIGQUIT only kills the current child and continues the input pipeline. So you can reach what you want by typing Ctrl-\ in the shell. Actually tail does not care about signals and leaves the default set (I guess). So a SIGQUIT might cause a core dump (see signal(7)). But you can also send a SIGINT to the tail process directly, which simply kills the child and leaves the input pipeline as is. echo "start shell: $$"; tail -f /tmp/watch-document ; echo "stop shell" then in another terminal ps -efa | grep PID # (PID = the number after "start shell: " output) ingo@krabbe ~/src/laboratory/shell $ ps -efa|grep 7946 ingo 7946 3859 0 17:22 pts/6 00:00:00 -bash ingo 24238 7946 0 18:35 pts/6 00:00:00 tail -f /tmp/watch-document There you see the PID of the tail and you can explicitly send a signal to the tail: kill -s 3 24328 # in my example case To make all of this more comfortable it is usefull to read the pid of the tail in the command sequence: echo "start shell: $$"; tail -f /tmp/watch-document & pid="$!"; echo "$pid" >>/tmp/watch-document.pid; wait "$pid"; echo "stop shell" By this way you will NOT quit the tail by CTRL+C, but you will call kill `cat /tmp/watch-document.pid` To kill all started subprocesses to watch /tmp/watch-document that are started this way. Actually the tail command needs to behave the way it is, because it is part of an essential set of POSIX tools that should behave exactly as defined. If you want to send a "*q*" to the tail to control it, on what input line do you want to send it there? The tail process simply reads stdin, so that tail -f somefile is the same as some-output-producer | tail -f In the latter command line, you have tail -f to watch the stdout of some command, which is a very important use case. This tail -f could simply go down whe the "some-output-producer" sends EOF on the stdout channel (by closing it, for example). What I want to say is: tail MUST stay agnostic to its input. If you have "*q*" somewhere in your "some-output-producer" line it should ot quit, but simply read it. This way you can freely model such sequences: some-output-producer | tail -f | some-output-handler Where "some-output-handler" could for example react on the "tail -f" output, by sending a signal to "some-output-handler", for example with awk: #!/usr/bin/awk -f /\*q\*/ { kill -s 2 "`cat /tmp/watch-document.pid`"; print "" >"/tmp/watch-document.pid"; exit 0; } { print } This way you can define your command language that depends on your own process. That's the way how these coreutils POSIX commands should work: You can combine them and use them for your own process language. They stay agnostic to the input as far as possible. Best regards Ingo On 21/10/18 11:13, Brian Wengel wrote: Dear coreutils maintainer team It seem you can only exit “tail –f…” sending *CTRL+C*, but that can be an issue if you call it from another process that you want to keep running after tail has exited. Another example is “start daemon; tail -F logfile; stop daemon” as user2394284 commented in this StackExchange <https://askubuntu.com/questions/36785/tail-how-to-quit-tail-and-restore-terminal-window> thread. A good and gentle way to exit could be sending “*q*” just as e.g. “journalctl –b” do. I hope you'll consider my request. And of course, a big thanks for the effort you put into the coreutils :-) Best regards Brian Denmark
Whats the reason to suppress short unicode characters in printf?
Hey gnu wizards, today I subscribed to this mailing list for a more or less philosphical question, that is already the subject of this mail: Whats the reason to suppress short unicode characters in printf? But lets start with a bit of historical background how I stumbled over the following issue. As many linux users I'm a terminal junkie, or better I was a terminal junkie, until I discovered even better ways to edit and fire command lines, but that would be part of another big story. So to help me to locate unicode characters, I wrote a little script, that does it's best to print out any unicode character on a table #!/bin/sh if [ $# -lt 1 ] then echo too few arguments. I need the table in hex form xxx, where the lower byte will be replaced. exit 1 fi eval let t=0x$1 echo TABLE $t let c=$(tput cols) let c=$c\/16 let ci=0 for i in {0..255} do C=$(/usr/bin/printf "U000%03x%02x" $t $i) form="%03x%02x: $C\t" /usr/bin/printf "$form" $t $i let ++ci if [ $ci -ge $c ] then /usr/bin/printf "\n" let ci=0 fi done . This script might not be the best approach, but still is quite usefull. For example # unicode-table-yyy 001 gives TABLE 1 00100: Ā00101: ā00102: Ă00103: ă00104: Ą […] 001fa: Ǻ001fb: ǻ001fc: Ǽ001fd: ǽ001fe: Ǿ 001ff: ǿ that I also use to copy&paste in tmux terminals if I need a character in a selected range. Of course it helps to have a full unicode font installed. But when I want to show the table #0 I get some errors, such as […] 0003c: /usr/bin/printf: invalid universal character name \U003c 0003d: /usr/bin/printf: invalid universal character name \U003d 0003e: /usr/bin/printf: invalid universal character name \U003e 0003f: /usr/bin/printf: invalid universal character name \U003f 00040: @ […] , where `man -s 1 printf` tells us to use \U Unicode character with hex value (8 digits) that is implemented in a very complex way to support some seldom used terminals with non utf-8 encodings (I hope non utf-8 encodings are seldom these days.) 263 else if (*p == 'u' || *p == 'U') 264 { 265 char esc_char = *p; 266 unsigned int uni_value; 267 268 uni_value = 0; 269 for (esc_length = (esc_char == 'u' ? 4 : 8), ++p; 270esc_length > 0; 271--esc_length, ++p) 272 { 273 if (! isxdigit (to_uchar (*p))) 274 error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape")); 275 uni_value = uni_value * 16 + hextobin (*p); 276 } 277 278 /* A universal character name shall not specify a character short 279 identifier in the range through 0020, 007F through 280 009F, or D800 through DFFF inclusive. A universal 281 character name shall not designate a character in the required 282 character set. */ 283 if ((uni_value <= 0x9f 284&& uni_value != 0x24 && uni_value != 0x40 && uni_value != 0x60) 285 || (uni_value >= 0xd800 && uni_value <= 0xdfff)) 286 error (EXIT_FAILURE, 0, _("invalid universal character name \\%c%0*x"), 287esc_char, (esc_char == 'u' ? 4 : 8), uni_value); 288 289 print_unicode_char (stdout, uni_value, 0); 290 } -- from coreutils-8.23 src/printf.c Again another story would be the implementation of `print_unicode_char`, but my case is the if clause [283,285] that suppresses some unicode values tables 000 and tables [0d8,0df]. Whats the reason for this exception? The reason against this exception is clearly, when you fail for some values of a set C, anyone who uses your program with input from set C has to implement these exceptions too. So such spikes in the input set, carry through the whole IO chain, that anyone who uses your `printf` program, has to implement this exceptions to implement an error free algorithm on input characters from set C, making the complex world of programming computer even more complex, as it intrinsically is anyway. Looking forward for an intresting discussion about complexity and with kind regards, Ingo Krabbe -- Liberty for the Modules! -- https://medium.com/@azerbike/i-ve-just-liberated-my-modules-9045c06be67c