Re: /bin/echo -- $var

2019-08-14 Thread Ingo Krabbe
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)

2018-10-21 Thread Ingo Krabbe

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?

2016-03-25 Thread Ingo Krabbe
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