[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: cat and pipelines, mostly (was Re: Delete all after a pattern)



On 2019-08-31 at 11:11, Roberto C. Sánchez wrote:

> On Sat, Aug 31, 2019 at 10:39:00AM -0400, The Wanderer wrote:
> 
>> On 2019-08-31 at 10:07, Roberto C. Sánchez wrote:
>> 
>> I actually think this is good behavior. The only obvious places to
>> put the cursor when doing command history are at the beginning of
>> the line and at the end, and for convenience-of-editing purposes,
>> the end seems obviously preferable to the beginning.
>> 
>> What possible shell behavior would you suggest that might be better
>> in this regard?
>> 
> When viewing the immediate prior command in history the cursor could 
> placed at the same position on the line as where it was found when
> the command was executed (most likely because the user presed
> 'enter').

Hmm.

That's arguable, yes.

I don't think I'd prefer it, because it would mean I'd have to remember
where I left the cursor last time rather than being able to just assume
it will always be in a particular position, but I can see that being
just a result of what I'm used to; I could see this being a better
behavior in the large, if one got used to it first.

(It seems as if would be kind of hard to implement, since you'd have to
embed a cursor position per-line into the command history file, but
that's another discussion.)

I don't suppose you know of any shells which have that behavior, even as
an option?

>>>> The further from the rightmost position the part you want to
>>>> edit is, the less convenient it is to do that editing,
>>>> especially when doing multiple trial-and-error passes to figure
>>>> out what syntax will actually produce the desired result.
>>> 
>>> Again, it sounds like a better shell is in order.
>> 
>> Again, better how?
>> 
> Better in that it behaves in the way you think it should.

I think you're making assumptions about how I think it should behave. I
kind of like the way the shell I have behaves, for the most part, and I
don't think this is one of the things I'd change.

>>> Here is an alternative that places the interesting commands as far
>>> to the right as possible:
>>> 
>>> $  i=~/test.txt; o=~/other_test.txt; (sed 's/config=.*$/config=/g' |
>>> tr -d '=') <${i} >${o}
>> 
>> <snip>
>> 
>>> That minimizes the distance between the end of the processing 
>>> command pipeline and the end of the line. You can add spaces
>>> before and/or after ';', '(', and ')' to create more explicit
>>> word boundaries if you like.
>> 
>> That's not a word boundary for the purposes of the keybindings
>> with which I'm familiar (and which seem to come enabled by default,
>> at least with bash; I think they actually come from readline). For
>> that purpose, only alphanumerics count as part of a word, and only
>> the boundary between a block of alphanumerics and whitespace counts
>> as the edge of a word.
>> 
>> That means falling back to one-character-at-a-time cursor
>> positioning, with the arrow keys, rather than being able to jump
>> around in larger blocks. Doable, but less convenient than not
>> needing to.
> 
> That particular problem still exists in your preferred approach.

But much less, and certainly not with every pipeline command - whereas
your suggested form, with punctuation at the end, means having to do it
every time.

>> (That syntax is also again more complicated to type than the simple
>> form I tend to use.)
> 
> But earlier you said that you type it once, then just hit the up
> arrow, tweak a few characters, and execute again until you obtain the
> desired result by trial and error.  In that case you are only typing
> the command once.

Just because I only type the command once doesn't mean that I want to
type a more complex command than I need to.

> Trying to optimize for simplicity one time one way while avoiding 
> other optimizations that yield a benefit every time seems rather 
> confusing to me.

I'm not sure exactly what optimizations, or benefit, you're referring
to. Aside from argument towards elegance, and possibly performance
optimization of some form, I'm not sure I see any benefit of the forms
you're suggesting.

>>> You'll notice that it's not about saving a process.  The better
>>> way involves a subshell '()' which will create a new process.
>> 
>> You're right, I had missed that.
>> 
>> In that case, I fail to see the benefit. As far as I can tell,
>> saving a process is the entire sum-total benefit of avoiding the
>> use of cat in this type of context.
>> 
> Then I am going to guess you have not had to maintain that many
> shell scripts.

That depends on what you mean by "maintain".

> As with any programming language, lowering the cognitive burden on
> the maintainer of a shell script should be a goal.  The more time I
> have to spend separating functional logic (like the sed 
> transformation) from non-functional logic (like here is where the
> input originates and here is where the output goes) the more likely I
> am to make a logic error and also the longer tasks will take in
> general.

True.

But I don't have to spend any time on separating the two. The beginning
of the command is where the input comes in; the end is where it goes
out; everything else is functional.

The form you provided that puts both at the end is complex and confusing
enough that I can't parse it at a glance; doing so only takes me a
second or two, but I do have to stop and do it, in what I suspect is
much the same way you have to stop and separate out the functional from
the input-handling in my preferred idiom.

Again, there's nothing wrong with your approach. What I'm saying is that
there's also nothing wrong with mine, and yet I get called out for using
(or even suggesting) it, for what as far as I can tell are purely
historical reasons.


>>> It is just as easy. However, 'cat' is not a value-added part of
>>> the processing pipeline. So, why have it at all?
>> 
>> Because of the value which is lost by avoiding it, which including
>> it preserves.
>> 
>> That value consists of both the convenience of editing from the end
>> of the line, and the intuitiveness of having the input come in at
>> the start and the output go out at the end.
>> 
> You're repeating yourself here.
> 
> If proximity to the end of the command line is a priority for the 
> functional logic, then do you use a variable to contain the name of
> the output file?
> 
> o=~/out.txt; ..... >${o}

No, because that's less convenient to type, and less intuitive in that
you have to look in two places to see what's happening: once where the
variable is defined, and once where it's used.

> Even for short file names that saves you several characters.  For
> long file names the savings are even better.
> 
> It seems like your argument is meant rather to keep you using your 
> specific constructs that you like even when based on your criteria
> there are better constructs available.

No, it's just that I disagree about what constitutes "better".

> That's fine, if you like your constructs, then keep using them. 
> However, it is somewhat disingenuous to argue a point (like you want 
> your functional command as close to the end of the command line as
> you can get it) then ignore a better approach that actually gets
> closer to your ideal than your current approach.

It's not "functional command", so much as "command I'm most likely to be
interested in editing".

And my ideal (as you put it) has multiple facets; I'm trying to optimize
towards the best balance of all of them. That's just the one which
seemed most relevant at that point in the discussion.

>> You seem to disagree that the latter is beneficial, or even
>> necessarily intuitive, so of course you prefer different
>> constructs. There's nothing wrong with that.
> 
> Agreed.
> 
>> I just get tired of having to explain my own preferred constructs 
>> labelled incorrect and inferior, rather than simply suited for
>> different interpretations of intuitiveness.
>> 
> Except that you are not simply arguing, "I like it this way because
> it is my preference."  You are arguing, "this way is better for
> these reasons."  Then when you are shown alternatives that better
> accomplish the things you claim are better about your approach, you
> repeat your arguments.

I disagree that the way the alternatives described accomplish that task
is better.

(Most of them, anyway. Teemu's suggestion seems obviously superior, at
least at a glance, and I may well adopt it going forward.)

I could try to break apart and analyze my reasons at length, but I kind
of doubt that the result would be all that productive.

>>> What is intuitive is not always right or best.  It is better to 
>>> properly learn the features and functions of the shell or other 
>>> environment so that proper separation can be made between
>>> business logic and supporting structures.
>> 
>> What makes it "proper"?
>> 
>> As far as I can tell, it's convenience and intuitiveness which
>> define "proper" in this context.
> 
> Perhaps.  However, it seems that we have differing views on
> convenience and intuitiveness, which is fine.

Agreed.

>>> If the command being worked on ends up in a script it is much
>>> easier to make the better form I suggested readable and
>>> maintainable than it is with the more 'intuitive' version.
>> 
>> Actually, some parts of my position on this come from work in
>> writing scripts.
>> 
>> I started out one particular script using a form which avoids the
>> use of cat, with a multi-stage pipeline split onto multiple lines,
>> so that I could move lines around conveniently with kill-and-yank
>> (and have the result show up readably in diffs).
>> 
>> Then I discovered that when I needed to insert a new command at
>> the beginning of the pipeline, I couldn't just kill-and-yank, I had
>> to also edit the syntax of the previous first line.
>> 
>> So I inserted a cat invocation as that first line, and thereafter
>> I could move lines around just as intended, without needing to
>> touch the first line again.
> 
> The same effect could have been achieved by making the first line a
> '(' and the last as ')' for the subshell enclosure.

That's an interesting thought. I'll try to keep it in mind for the next
time I'm doing something like that.

> However, your original description mentioned nothing regarding
> working in a multi-line context.

That's because it wasn't. I use the same idiom in multiple contexts, and
the context at hand was the interactive command line.

> Don't misunderstand me.  I sometimes start interactive command lines 
> with 'cat' followed by a pipe.  When I do that it is out of
> convenience more than anything else.  However, if I am writing
> something intended for a script and/or trying to optimize for the
> criteria you earlier described, then starting with 'cat' with just
> unncessary clutter that makes it harder to quickly discern what is
> really happening.

I can see the argument for clutter, but for my purposes, the extra
syntax of the forms you've suggested are even more clutter and make the
result even harder to read, thereby making it even harder to quickly
discern what is really happening.

I suspect that this just boils down to minds working differently.

-- 
   The Wanderer

The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all
progress depends on the unreasonable man.         -- George Bernard Shaw

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: