att/ast

<>; redirection operator doesn't work for the last command of a `ksh -c inline-script`

stephane-chazelas opened this issue · 7 comments

$ echo test > a; ksh -c 'echo x 1<>; a'; cat a
x
st

It's OK, if we insert a command after that:

$ echo test > a; ksh -c 'echo x 1<>; a; exit'; cat a
x

@stephane-chazelas Sorry for taking so long to respond to this issue.

This is what other shells do:

bash (devel branch):

echo test > a; ./bash -c 'echo x 1<> a'; cat a
x
st

zsh (zsh 5.5.1):

> echo test > a; zsh -c 'echo x 1<> a'; cat a
x
st

So this behavior is compatible with other shells. > operator causes a file to be overwritten, but <> does not overwrite a file. So this behavior seems expected.

What's more interesting is ksh behavior changes if I use 1<>; instead of 1<> with exit command:

echo test > a; ksh -c 'echo x 1<> a; exit'; cat a
x
st
echo test > a; ksh -c 'echo x 1<>; a; exit'; cat a
x

Ok, I see how <> is different from <>; in man page now:

 <>;word       The same as <>word except that if the command completes successfully, word is truncated to the offset at command completion.  <>;word cannot be used with the exec(2).  built-in.

So this is a bug.

Yes, this is technically a bug. But it has probably been broken since it was introduced on 2009-01-23 for the ksh93t+ release. From the lib/package/ast-open.README file:

09-01-23 +The redirection operator <>; was added. It is similar to <> except that if the command it is applied to succeeds, the file is truncated to the offset at the command completion.

It's hard to know if it was broken in the ksh93t+ release that introduced this feature. Or by a subsequent change in the ksh93u+ release. I can't readily test the former version but it is broken in the most recent public release. The fact this idiom is used in the src/cmd/ksh93/tests/io.sh unit test, and that test passes, suggests this feature has never been unit tested. Too, I don't understand how this would be meaningfully used in a ksh script. Yes, I have written lots of code that opens a file, updates its content, and truncates it to a specific length. But I have never expected to be able to do this in a shell script.

What is the probability anyone is using this feature? It seems to me to be zero or so close to zero that we don't care.

FWIW, I would be happy to retain this feature if it weren't for the fact the code has so many bugs involving its core functionality that support for such fringe features is hard to justify.

This is another bug hiding behind non-forking subshells code. Commenting out this condition fixes this issue.

If this code was in better shape, I would have been willing to maintain non-forking subshells. As we move forward, I am getting less convinced that I am willing to take that effort.

Too, I don't understand how this would be meaningfully used in a ksh script. Yes, I have written lots of code that opens a file, updates its content, and truncates it to a specific length. But I have never expected to be able to do this in a shell script.

What is the probability anyone is using this feature? It seems to me to be zero or so close to zero that we don't care.

It's useful to edit a file in place when the editing doesn't add data (like with tr -d, grep...). That's one feature I'd love being added to other shells.

See

https://unix.stackexchange.com/a/265857
https://unix.stackexchange.com/a/271210
https://unix.stackexchange.com/a/299434
https://unix.stackexchange.com/a/305664
https://unix.stackexchange.com/a/367066
https://unix.stackexchange.com/a/427275
https://unix.stackexchange.com/a/46623
https://unix.stackexchange.com/a/57021
https://unix.stackexchange.com/a/337627

For some examples. (in the first one, it's used as just a truncating operator in combination with >#((...))).

@stephane-chazelas Thanks again for bringing this issue to our attention. It's a shame that it took more than 2 years to fix this bug. But as you can see in several other bugs reports, we are fixing bugs that are close to 2 decades old. Despite of all the problems we are dealing with, I still remain optimistic and I would love to see more comments from people like you who have solid understanding of POSIX internals.