* virtual files? @ 2016-04-20 1:00 Emanuel Berg 2016-04-20 1:27 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 3:32 ` Benjamin R. Haskell 0 siblings, 2 replies; 15+ messages in thread From: Emanuel Berg @ 2016-04-20 1:00 UTC (permalink / raw) To: zsh-users Here is a program I just wrote. Feel free to comment on any part. However my specific question is, instead of using the "result_file" stuff, is there support for I suppose "virtual files" or basically a data structure that can be used transparently as a file, or with but small adjustments? TIA. #! /bin/zsh # This file: http://user.it.uu.se/~embe8573/conf/.zsh/money # zsh CLI to Internet inflation calculator. # # Try, for example, three K2 expeditions: # # $ inflation 9000 1938; inflation 30958.33 1953; inflation 108000 1954 # # which yields: # # $151,999.15 # $276,111.20 # $956,069.00 inflation () { local usd=${1:-10} # year local then=${2:-1950} local now=`date +"%Y"` local result_file=result local link="http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" wget -q $link -O $result_file echo -n \$ grep \"answer\" $result_file | cut -d \$ -f 2 | cut -d \< -f 1 rm $result_file } -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 25 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 1:00 virtual files? Emanuel Berg @ 2016-04-20 1:27 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 2:12 ` Emanuel Berg 2016-04-20 3:32 ` Benjamin R. Haskell 1 sibling, 1 reply; 15+ messages in thread From: Nikolay Aleksandrovich Pavlov (ZyX) @ 2016-04-20 1:27 UTC (permalink / raw) To: Emanuel Berg, zsh-users 20.04.2016, 04:19, "Emanuel Berg" <embe8573@student.uu.se>: > Here is a program I just wrote. > > Feel free to comment on any part. > > However my specific question is, instead of using the > "result_file" stuff, is there support for > I suppose "virtual files" or basically a data structure > that can be used transparently as a file, or with but > small adjustments? > > TIA. > > #! /bin/zsh > > # This file: http://user.it.uu.se/~embe8573/conf/.zsh/money > > # zsh CLI to Internet inflation calculator. > # > # Try, for example, three K2 expeditions: > # > # $ inflation 9000 1938; inflation 30958.33 1953; inflation 108000 1954 > # > # which yields: > # > # $151,999.15 > # $276,111.20 > # $956,069.00 > > inflation () { > local usd=${1:-10} > > # year > local then=${2:-1950} > local now=`date +"%Y"` > > local result_file=result > > local link="http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" > wget -q $link -O $result_file > > echo -n \$ > grep \"answer\" $result_file | cut -d \$ -f 2 | cut -d \< -f 1 > > rm $result_file > } In some cases you may use `>(process)` to create file descriptor that will be used like a named pipe and may replace real files in some cases (it does not support seek(), also some processes have a habit of closing all file descriptors except stdin/stdout/stderr). But it is launched in subshell which limits the usefullness further (i.e. you cannot directly save result in a variable). Specifically this function does not need >() or any file at all: … echo -n \$ wget -q $link -O- | grep answer | cut -d \$ -f2 | cut -d \< -f1 … > > -- > underground experts united .... http://user.it.uu.se/~embe8573 > Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic > - so far: 25 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 1:27 ` Nikolay Aleksandrovich Pavlov (ZyX) @ 2016-04-20 2:12 ` Emanuel Berg 2016-04-20 2:31 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 4:03 ` Bart Schaefer 0 siblings, 2 replies; 15+ messages in thread From: Emanuel Berg @ 2016-04-20 2:12 UTC (permalink / raw) To: zsh-users "Nikolay Aleksandrovich Pavlov (ZyX)" <kp-pav@yandex.ru> writes: > In some cases you may use `>(process)` to create > file descriptor that will be used like a named pipe > and may replace real files in some cases (it does > not support seek(), also some processes have a habit > of closing all file descriptors except > stdin/stdout/stderr). But it is launched in subshell > which limits the usefullness further (i.e. > you cannot directly save result in a variable). OK! That doesn't seem like any good samochuvstvie... > Specifically this function does not need >() or any > file at all: > > ... echo -n \$ wget -q $link -O- | grep answer | cut > -d \$ -f2 | cut -d \< -f1 ... But you still need the escaped quotes around "answer" otherwise it won't work due to the HTML data :) Now, it is true you don't *need* files here or in other situations like this. But it is a very good thing to have, to be able to name something something, and then stash the result there for future use. A variable or data structure, in essence. Obviously creating a normal file just to remove it last thing doesn't score you any hacker points... So I think this is a good idea for you to contemplate incorporating in zsh! -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 25 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 2:12 ` Emanuel Berg @ 2016-04-20 2:31 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 4:03 ` Bart Schaefer 1 sibling, 0 replies; 15+ messages in thread From: Nikolay Aleksandrovich Pavlov (ZyX) @ 2016-04-20 2:31 UTC (permalink / raw) To: Emanuel Berg, zsh-users 20.04.2016, 05:13, "Emanuel Berg" <embe8573@student.uu.se>: > "Nikolay Aleksandrovich Pavlov (ZyX)" > <kp-pav@yandex.ru> writes: > >> In some cases you may use `>(process)` to create >> file descriptor that will be used like a named pipe >> and may replace real files in some cases (it does >> not support seek(), also some processes have a habit >> of closing all file descriptors except >> stdin/stdout/stderr). But it is launched in subshell >> which limits the usefullness further (i.e. >> you cannot directly save result in a variable). > > OK! That doesn't seem like any good samochuvstvie... > >> Specifically this function does not need >() or any >> file at all: >> >> ... echo -n \$ wget -q $link -O- | grep answer | cut >> -d \$ -f2 | cut -d \< -f1 ... > > But you still need the escaped quotes around "answer" > otherwise it won't work due to the HTML data :) > > Now, it is true you don't *need* files here or in > other situations like this. But it is a very good > thing to have, to be able to name something something, > and then stash the result there for future use. > A variable or data structure, in essence. For `wget -Ofoo` there may not be any variable/data structure. At all, file `foo` in this example is created by *wget*, zsh *cannot* intervent here: all it knows is that `wget` received argument `-Ofoo` which is a plain string like any other argument, it does not know what `foo` is (completion system is a separate thing and it can only make *guesses*, not know for sure). If you really need this you can create something like temporary tmpfs via FUSE which will be automatically unmounted when scripts exits, and this does not require any special support on zsh side. As the other alternative one may create something like `=()` to work like “create temporary file, substitute its name here, after process finishes save file contents in the variable and remove it”. Basically a syntactic sugar for what you currently are doing, should be relatively easy (I did not look at relevant parts of the code though). Most of time this is not really needed: you may simply use stdout or stderr. Least of time… well, this is a *shell* language, complex applications were never its target. I believe this is why better integration with subprocesses is not implemented yet, though I sometimes see problems which would be solved much easier if e.g. when opening subshell zsh created a file descriptor through which updates to variables would be directed (i.e. something like a command socket, but through a pipe). > > Obviously creating a normal file just to remove it > last thing doesn't score you any hacker points... > > So I think this is a good idea for you to contemplate > incorporating in zsh! > > -- > underground experts united .... http://user.it.uu.se/~embe8573 > Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic > - so far: 25 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 2:12 ` Emanuel Berg 2016-04-20 2:31 ` Nikolay Aleksandrovich Pavlov (ZyX) @ 2016-04-20 4:03 ` Bart Schaefer 2016-04-20 6:06 ` Emanuel Berg 2016-04-21 22:14 ` Emanuel Berg 1 sibling, 2 replies; 15+ messages in thread From: Bart Schaefer @ 2016-04-20 4:03 UTC (permalink / raw) To: zsh-users On Apr 20, 2:12am, Emanuel Berg wrote: } } Obviously creating a normal file just to remove it } last thing doesn't score you any hacker points... } } So I think this is a good idea for you to contemplate } incorporating in zsh! The problem is that implementing something like this in the shell is fairly useless, because none of the other tools that the shell might invoke would know what to do with it. This is why you need something operating-system-level like FUSE (as Nikolay mentioned), which can make the virtual object "look like" an ordinary file or descriptor to anything using the ordinary libraries/interfaces. Also as Nikolay sort of mentioned in passing, you can replace local result_file=result wget -q $link -O $result_file grep \"answer\" $result_file | ... rm $result_file with grep \"answer\" =(wget -q $link -O -) | ... and zsh will take care of creating/removing the temp file for you. You can further do exec {result_fd}< =(wget -q $link -O -) and now $result_fd is a descriptor holding open an unlinked file. If you load the zsh/system module, you can grep \"answer\" <&$result_fd | ... sysseek -u $result_id 0 If all you're wanting is to capture output in a variable, you can use the "read" command (or use "sysread" from zsh/system). Zsh arranges for "read" at the tail of a pipe to execute in the current shell (unlike most other shells that put the pipe tail in a subshell) so wget -q $link -O - | read -d '' result loads the output of wget directly into $result. There are other things you can do e.g. with the zsh/mapfile module or the zsh/db/gdbm module (I recommend a very recent zsh if you plan to do anything serious with the latter), but I've rambled enough. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 4:03 ` Bart Schaefer @ 2016-04-20 6:06 ` Emanuel Berg 2016-04-21 22:14 ` Emanuel Berg 1 sibling, 0 replies; 15+ messages in thread From: Emanuel Berg @ 2016-04-20 6:06 UTC (permalink / raw) To: zsh-users Bart Schaefer <schaefer@brasslantern.com> writes: > ... but I've rambled enough. Ha ha, good rambling from all three of you! God willing I'll be back with a few more questions after I make a closer reading of this material. -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 26 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 4:03 ` Bart Schaefer 2016-04-20 6:06 ` Emanuel Berg @ 2016-04-21 22:14 ` Emanuel Berg 2016-04-22 1:08 ` Bart Schaefer 1 sibling, 1 reply; 15+ messages in thread From: Emanuel Berg @ 2016-04-21 22:14 UTC (permalink / raw) To: zsh-users Bart Schaefer <schaefer@brasslantern.com> writes: > The problem is that implementing something like this > in the shell is fairly useless, because none of the > other tools that the shell might invoke would know > what to do with it. This is why you need something > operating-system-level like FUSE (as Nikolay > mentioned), which can make the virtual object "look > like" an ordinary file or descriptor to anything > using the ordinary libraries/interfaces. That sure is the international superstar hitman approach but it appears to be overkill (ha) not only for this example but also for whatever else I've done and am doing at the zsh and CLI tool level. Also there is some virtue in having the software which you use the most at some level of isolation from the OS (or the OS below I should say). It is a good feeling, and an efficient method, to just be able to bring over your Emacs and zsh gear from one system to another and virtually have the same user experience, all but instantly. And I have actually succeeded doing that! Sometimes... > If all you're wanting is to capture output in > a variable, you can use the "read" command (or use > "sysread" from zsh/system). Zsh arranges for "read" > at the tail of a pipe to execute in the current > shell (unlike most other shells that put the pipe > tail in a subshell) so > > wget -q $link -O - | read -d '' result > > loads the output of wget directly into $result. ... :O I can't believe I missed this the first time I read this message! But if I hadn't, I wouldn't have learned about the () { } =() thing so I suppose it was my ancestors having my back, as always. "If all you're wanting"...? :) But yes, this is exactly what I want! read-test () { local url=http://data.bls.gov/cgi-bin/cpicalc.pl local result wget -q $url -O - | read -d '' result echo $result } (I suppose the "delimiter" is EOF if set to nothing.) Now I'll dig deep into all my shell programming and see if I can prune some unnecessary creation and removal of filesystem files. Delightful! -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 26 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-21 22:14 ` Emanuel Berg @ 2016-04-22 1:08 ` Bart Schaefer 0 siblings, 0 replies; 15+ messages in thread From: Bart Schaefer @ 2016-04-22 1:08 UTC (permalink / raw) To: zsh-users On Apr 22, 12:14am, Emanuel Berg wrote: } } read-test () { } local url=http://data.bls.gov/cgi-bin/cpicalc.pl } local result } wget -q $url -O - | read -d '' result } echo $result } } You probably want print -r -- $result to avoid any leading hyphens or other misc. sequences in $result from being interpreted by echo. } (I suppose the "delimiter" is EOF if set to nothing.) Effectively yes. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 1:00 virtual files? Emanuel Berg 2016-04-20 1:27 ` Nikolay Aleksandrovich Pavlov (ZyX) @ 2016-04-20 3:32 ` Benjamin R. Haskell 2016-04-20 20:34 ` Bart Schaefer 2016-04-21 4:12 ` Emanuel Berg 1 sibling, 2 replies; 15+ messages in thread From: Benjamin R. Haskell @ 2016-04-20 3:32 UTC (permalink / raw) To: Zsh-Users List [-- Attachment #1: Type: text/plain, Size: 3760 bytes --] On Tue, Apr 19, 2016 at 9:00 PM, Emanuel Berg <embe8573@student.uu.se> wrote: > Here is a program I just wrote. > > Feel free to comment on any part. > > However my specific question is, instead of using the > "result_file" stuff, is there support for > I suppose "virtual files" or basically a data structure > that can be used transparently as a file, or with but > small adjustments? > > TIA. > > #! /bin/zsh > > # This file: http://user.it.uu.se/~embe8573/conf/.zsh/money > > # zsh CLI to Internet inflation calculator. > # > # Try, for example, three K2 expeditions: > # > # $ inflation 9000 1938; inflation 30958.33 1953; inflation 108000 1954 > # > # which yields: > # > # $151,999.15 > # $276,111.20 > # $956,069.00 > > inflation () { > local usd=${1:-10} > > # year > local then=${2:-1950} > local now=`date +"%Y"` > > local result_file=result > > local link=" > http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" > wget -q $link -O $result_file > > echo -n \$ > grep \"answer\" $result_file | cut -d \$ -f 2 | cut -d \< -f 1 > > rm $result_file > } > Using the `=()` substitution ZyX mentions: inflation () { local usd=${1:-10} # year local then=${2:-1950} local now=`date +"%Y"` local link=" http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" () { local tmp=$1 wget -q $link -O $tmp echo -n \$ grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 } =(:) } The '() { ... }' construct is an anonymous function, just for controlling the scope of the temporary file, and for passing it in as a positional parameter. It has the disadvantage that it won't remove the tmp file if something goes wrong. Personally, for portable scripts (not usually functions), I tend to use `mktemp` + `trap cleanup INT QUIT EXIT` (where `cleanup` is a per-script function for removing whatever temp files I create in that script). E.g., in this case, since it's a single tmp file, you may as well inline the trap body: inflation () { local usd=${1:-10} # year local then=${2:-1950} local now=`date +"%Y"` local link=" http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" # not sure which of these are default: setopt local_options no_posix_traps local_traps err_return # -t means "use $TMPDIR" for some `mktemp`s, "next arg is template" for others local tmp=$(mktemp -t inflation.data.XXXXXXXX) # remove the tmp file on exit, if it was set up properly trap '[[ -z $tmp ]] || rm $tmp' INT QUIT EXIT wget -q $link -O $tmp echo -n \$ grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 } Another possibility is the use of `coproc` (which I only see mentioned twice in `zshall(1)`), so I feel like it doesn't get used often, and only works in this case because `wget` is capable of using stdout: (but is nonetheless potentially interesting): inflation () { local usd=${1:-10} # year local then=${2:-1950} local now=`date +"%Y"` local link=" http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" coproc wget -q $link -O - echo -n \$ grep \"answer\" <&p | cut -d \$ -f 2 | cut -d \< -f 1 } The `coproc` preceding the `wget` starts a background process, then `>&p` = write to the process (not used here), `<&p` = read from the process (used for the input to `grep`). Also, I prefer `curl` over `wget`, and if you're curious, here's how I might write the entire function: inflation() { curl -s -d cost1=${1:-10} -d year1=${2:-1950} -d year2=$(date +%Y) \ http://data.bls.gov/cgi-bin/cpicalc.pl | awk '/"answer"/' | tr -d -c '$0-9.,\n' } (Though the create-a-tempfile problem is certainly interesting in its own right.) -- Best, Ben ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 3:32 ` Benjamin R. Haskell @ 2016-04-20 20:34 ` Bart Schaefer 2016-04-22 5:26 ` Benjamin R. Haskell 2016-04-21 4:12 ` Emanuel Berg 1 sibling, 1 reply; 15+ messages in thread From: Bart Schaefer @ 2016-04-20 20:34 UTC (permalink / raw) To: Zsh-Users List On Apr 19, 11:32pm, Benjamin R. Haskell wrote: } } Using the `=()` substitution ZyX mentions: } } () { } local tmp=$1 } wget -q $link -O $tmp } echo -n \$ } grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 } } =(:) } } The '() { ... }' construct is an anonymous function, just for controlling } the scope of the temporary file, and for passing it in as a positional } parameter. It has the disadvantage that it won't remove the tmp file if } something goes wrong. In fact the point of using =(:) is that it WILL remove the tmp file if something goes wrong (unless it's something completely catastrophic like the shell itself crashing, but in that case an explicit "rm" wouldn't work either). Instead of exit traps, you can use "always" blocks: () { local tmp=$1; { : do stuff with $tmp exit } always { rm $tmp } } =(:) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 20:34 ` Bart Schaefer @ 2016-04-22 5:26 ` Benjamin R. Haskell 0 siblings, 0 replies; 15+ messages in thread From: Benjamin R. Haskell @ 2016-04-22 5:26 UTC (permalink / raw) To: Bart Schaefer; +Cc: Zsh-Users List [-- Attachment #1: Type: text/plain, Size: 1547 bytes --] On Wed, Apr 20, 2016 at 4:34 PM, Bart Schaefer <schaefer@brasslantern.com> wrote: > On Apr 19, 11:32pm, Benjamin R. Haskell wrote: > } > } Using the `=()` substitution ZyX mentions: > } > } () { > } local tmp=$1 > } wget -q $link -O $tmp > } echo -n \$ > } grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 > } } =(:) > } > } The '() { ... }' construct is an anonymous function, just for controlling > } the scope of the temporary file, and for passing it in as a positional > } parameter. It has the disadvantage that it won't remove the tmp file if > } something goes wrong. > > In fact the point of using =(:) is that it WILL remove the tmp file if > something goes wrong (unless it's something completely catastrophic like > the shell itself crashing, but in that case an explicit "rm" wouldn't > work either). > Right, it's the "unless" I'm worried about: ## temp file isn't deleted on exit, so it's still there to be removed $ ( () { local tmp=$1 ; echo $tmp ; exit 1 } =(:) ) | xargs rm --verbose removed '/tmp/zsh9OzJL1' ## temp file is deleted with exit trap $ ( () { local tmp=$1 ; trap "rm $tmp" INT QUIT EXIT ; echo $tmp ; exit 1 } =(:) ) | xargs rm --verbose rm: cannot remove '/tmp/zshhzsFQo': No such file or directory Instead of exit traps, you can use "always" blocks: > > () { > local tmp=$1; > { > : do stuff with $tmp > exit > } always { > rm $tmp > } > } =(:) > Cool! ~Half my scripts have no need of POSIX-ness, so that'll come in handy. -- Best, Ben ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-20 3:32 ` Benjamin R. Haskell 2016-04-20 20:34 ` Bart Schaefer @ 2016-04-21 4:12 ` Emanuel Berg 2016-04-21 6:58 ` Bart Schaefer 2016-04-22 5:55 ` Benjamin R. Haskell 1 sibling, 2 replies; 15+ messages in thread From: Emanuel Berg @ 2016-04-21 4:12 UTC (permalink / raw) To: zsh-users "Benjamin R. Haskell" <zsh@benizi.com> writes: > Using the `=()` substitution ZyX mentions: > > inflation () { > local usd=${1:-10} > # year > local then=${2:-1950} > local now=`date +"%Y"` > local link=" > http://data.bls.gov/cgi-bin/cpicalc.pl?cost1=$usd&year1=$then&year2=$now" > () { > local tmp=$1 > wget -q $link -O $tmp > echo -n \$ > grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 > } =(:) > } Great! If was something like that I had in mind. Tho the mental image was more like the Lisp syntax for doing scopes, e.g. `let' and `with-selected-frame' in: (defun new-frame-show-grep () (let ((new-frame (make-frame-command))) (setq *grep-frame* new-frame) (with-selected-frame new-frame (switch-to-buffer "*grep*") ))) Actually the zsh anonymous function syntax doesn't remind me of anything I've seen, save for perhaps some stuff in zsh itself. The parameter list and body without a name make sense, but what comes after the closing curly bracket looks like a ghost, wearing a tie... What is the colon in =(:) - an "anonymous function qualifier"? Only remark is, if you do all this trouble to get clean code, and then name the local "tmp", it is almost comical. But I get it, you did that for me (all readers), not the code per se... > Also, I prefer `curl` over `wget`, and if you're > curious, here's how I might write the entire > function: I have used them both and never reflected on which was superior, but taking a look at your code: > inflation() { > curl -s -d cost1=${1:-10} -d year1=${2:-1950} -d year2=$(date +%Y) \ > http://data.bls.gov/cgi-bin/cpicalc.pl | > awk '/"answer"/' | > tr -d -c '$0-9.,\n' > } I agree that using the --data's to set up the CGI-to-be-Perl-input arguments is less hackish than putting together the URL manually (fine, just once, but anyway is much less clear). Ironic thing is, doing it manually might actually be faster since you can then just copy-paste and modify the URL. So anyway I changed to curl, only I somewhat didn't use your compact style. awk instead of grep in this context should be strange to many who are more familiar with grep, but grep has the problem that many like to put colorization to it which can screw up parsing. If the configuration is in an environmental, I suppose not even giving the full path to the binary to bypass an alias would get them away. One can supply a specification, of course, telling grep not to use colors, but rather than doing that, I switched to awk as you suggested. I also changed the two cut:s for tr, and date +%Y from the `one` syntax form into $(another). Those I consider even more minor improvements, however they are still better so I changed them as well. If it is meaningless to do, I might as well do it! So here is the latest version: inflation () { local url=http://data.bls.gov/cgi-bin/cpicalc.pl curl -s \ -d cost1=${1:-10} \ -d year1=${2:-1950} \ -d year2=$(date +%Y) $url | awk '/"answer"/' | tr -d -c '$0-9.,\n' } One interesting thing is tho I changed three programs out of three used, I don't think this function is anything "remote" to the one I originally wrote. A small homage to the diversity of the Linux/Unix tools, I suppose. But come to think of it there are many players in the NHL that score some ~15 goals every season, but that doesn't mean they cannot also be completely different players, physical aspects as well as those of skill and style... > (Though the create-a-tempfile problem is certainly > interesting in its own right.) Yes. It cannot be like this for too many steps, is my take: a | b | ... | n But this looks like some TI-82 stuff I kid would do let f=file_path # do things to f rm $f As for now, what I'll do is to keep it short, stupid! (KISS - Thatcher quote, I think) and so be able to put together parsings, and when that doesn't work as in longer pieces of software, I'll consider getting som order by use of the anonymous software. http://user.it.uu.se/~embe8573/conf/.zsh/money -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 26 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-21 4:12 ` Emanuel Berg @ 2016-04-21 6:58 ` Bart Schaefer 2016-04-21 8:05 ` Emanuel Berg 2016-04-22 5:55 ` Benjamin R. Haskell 1 sibling, 1 reply; 15+ messages in thread From: Bart Schaefer @ 2016-04-21 6:58 UTC (permalink / raw) To: zsh-users On Apr 21, 4:12am, Emanuel Berg wrote: } } What is the colon in =(:) - an "anonymous function } qualifier"? The syntax =(command) runs command and captures its output in a temp file, then substitutes the name of the temp file; the file itself is removed as soon as the current command finishes. So echo =(echo foo) will print something like /tmp/zshhKNk2F and cat =(echo foo) will print foo. Thus () { cat $1 } =(echo foo) also prints foo. The ":" command is just a quick built-in no-op that produces no output, so that the temporary file created by =(:) will be empty. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-21 6:58 ` Bart Schaefer @ 2016-04-21 8:05 ` Emanuel Berg 0 siblings, 0 replies; 15+ messages in thread From: Emanuel Berg @ 2016-04-21 8:05 UTC (permalink / raw) To: zsh-users Bart Schaefer <schaefer@brasslantern.com> writes: > Thus > > () { cat $1 } =(echo foo) > > also prints foo. The ":" command is just a quick > built-in no-op that produces no output, so that the > temporary file created by =(:) will be empty. Got it! This also means if you want to have several local files (names to temporary files) in the same limited scope you have to stack several =(:) as well! -- underground experts united .... http://user.it.uu.se/~embe8573 Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic - so far: 26 Blogomatic articles - ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: virtual files? 2016-04-21 4:12 ` Emanuel Berg 2016-04-21 6:58 ` Bart Schaefer @ 2016-04-22 5:55 ` Benjamin R. Haskell 1 sibling, 0 replies; 15+ messages in thread From: Benjamin R. Haskell @ 2016-04-22 5:55 UTC (permalink / raw) To: Zsh-Users List [-- Attachment #1: Type: text/plain, Size: 2394 bytes --] On Thu, Apr 21, 2016 at 12:12 AM, Emanuel Berg <embe8573@student.uu.se> wrote: > "Benjamin R. Haskell" <zsh@benizi.com> writes: > > > [...] > > () { > > local tmp=$1 > > wget -q $link -O $tmp > > echo -n \$ > > grep \"answer\" $tmp | cut -d \$ -f 2 | cut -d \< -f 1 > > } =(:) > > } > > [...] > > Only remark is, if you do all this trouble to get > clean code, and then name the local "tmp", it is > almost comical. I like to think of it as a lingering code smell. Don't need a tmp file after all. ;-) [...] > > awk '/"answer"/' | > > awk instead of grep in this context should be strange > to many who are more familiar with grep, but grep has > the problem that many like to put colorization to it > which can screw up parsing. If the configuration > is in an environmental, I suppose not even giving the > full path to the binary to bypass an alias would get > them away. One can supply a specification, of course, > telling grep not to use colors, but rather than doing > that, I switched to awk as you suggested. > I tend to prefer awk for a few reasons: 1. Whatever I wanted to `grep` usually needs some small amount of post-processing. (not in this case, but usually scope expands.) 2. It's often one fewer pipe than a `grep ... | cut ...` 3. In a lot of contexts it's nice that it doesn't exit non-zero even if nothing matches. 4. Its implementations tend to be very consistent (no worries about GNU vs non-GNU or Linux/other that often arise with other utilities), so it's a good command to learn. I also changed the two cut:s for tr, and date +%Y from > the `one` syntax form into $(another). > I strongly favor $(another) due to its nestability. [...] > One interesting thing is tho I changed three programs > out of three used, I don't think this function is > anything "remote" to the one I originally wrote. > A small homage to the diversity of the Linux/Unix > tools, I suppose. But come to think of it there are > many players in the NHL that score some ~15 goals > every season, but that doesn't mean they cannot also > be completely different players, physical aspects as > well as those of skill and style... > I noticed that I'd changed all the tools you used, too. It's also fun to notice that (maybe?) 5 years ago, I probably would've used Perl for the whole pipeline, but these days I pretty rarely fall back to it. -- Best, Ben ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-04-22 5:55 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-04-20 1:00 virtual files? Emanuel Berg 2016-04-20 1:27 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 2:12 ` Emanuel Berg 2016-04-20 2:31 ` Nikolay Aleksandrovich Pavlov (ZyX) 2016-04-20 4:03 ` Bart Schaefer 2016-04-20 6:06 ` Emanuel Berg 2016-04-21 22:14 ` Emanuel Berg 2016-04-22 1:08 ` Bart Schaefer 2016-04-20 3:32 ` Benjamin R. Haskell 2016-04-20 20:34 ` Bart Schaefer 2016-04-22 5:26 ` Benjamin R. Haskell 2016-04-21 4:12 ` Emanuel Berg 2016-04-21 6:58 ` Bart Schaefer 2016-04-21 8:05 ` Emanuel Berg 2016-04-22 5:55 ` Benjamin R. Haskell
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).