Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: append to history entry?



On 28/12/16 03:34 PM, Daniel Shahaf wrote:

Just consider the following cases (there are more, but you should get
the gist):

Sure, no surprise there, of course only the parser knows one semicolon from the next but as Bart says, the history string is saved way before the parser gets to it, so it sounds like I can have my strings, but not robustly check for separation of commands.
What are you trying to do now?  This is no longer your original
question about recording the hostname in history.

Is this about 'rap' being called in the middle of a command line…?
It's mostly for my command wrappers. The thing is to make it possible to see the 'real' command being run by the wrapper. I have it mostly satisfactory but the
method is belaboured.  For example 'l' wraps 'ls'.  If I do:

/boot $ l ,R *amd64 ( 'R' meaning sort and tabulate from the right)

in my /boot directory I get:
|
| || |1   4153384  2016-12-17/09:56:35 vmlinuz-4.8.0-2-amd64||
|| 1   3161213  2016-12-17/09:56:35 System.map-4.8.0-2-amd64||
|| 1  17655948  2016-12-27/15:59:03 initrd.img-4.8.0-2-amd64||
|| 1    183632  2016-12-17/09:56:35 config-4.8.0-2-amd64||
||
|but, what did the wrapper do to get that?  It did this:

$ ls -AGFrgt --time-style=+%F/%T --group-directories-first *amd64 | egrep -v '^total' | rev | sort -r | column -t | rev | cut --delimiter=' ' --fields=3-

How it works is that I start the function thusly:

alias l='noglob _l'
function _l ()
{
.... process various switches, cobbling together the real command ending up with:
_execute $command-string
}
... and '_execute' essentially does this:
|
||_execute ()||
||{ ||
||||print -rS "$*"||
|| echo "\nEXECUTING: ${@//'\'/\\\\}\n"||( more protecting backslashes :( )
||    eval "$@"||
||}||
|
... 'eval' of course expands and executes BUT the command has been pushed to history without glob expansion (which would obviously be impractical in many situations) so that I can recall the 'real' command as I choose.

That's useful for debugging the wrapper -- if the wrapper screws up, I just recall the real command and find out where the issue is. Also, I might want to modify the real command in some way and re-execute it since the wrappers themselves only handle routine usage. As it is now, variables are expanded which is no huge problem but if there was some way of grabbing the arguments to the command unexpanded I could just chew on those so that the command pushed to history was totally unexpanded as tho I had typed the real command in by hand. And of course 'eval' would take care of everything as far as execution anyway. The only time it gets unworkable is if some variable contains something huge, but 99% of the time, what I have now is functional, but on principal I'd still like to be able to have my entire command string unaltered , push the constructed real command to history with wildcards and variables as typed, and just have 'eval' expand everything as needed. I know it's sorta the opposite of what zsh is for, but having the real command available for recall can be hugely useful.

Here's another example:

/boot $ f ,Hd zsh* /

EXECUTING: find -H -O3 / -warn -xdev -iname "zsh*" -type d | grep -i --color=always zsh

/etc/zsh-virgin
/usr/share/zsh

... up arrow brings the real command right back in case I want to play with it some how or just see what the wrapper actually did.



Messages sorted by: Reverse Date, Date, Thread, Author