News for hackers. Stuff that matters.
Re:Useful Perl one-liners (2013) by EvilTerran on Tuesday November 29, 2016 @06:23PM (#13067088)
A personal favourite of mine:

    perl -lp0e1 /proc/$pid/environ
It relies on some fairly subtle interactions in perl's command-line processing, and I do enjoy how cunning that makes it feel. And it's actually useful, by way of being a lot easier to type (less moving your hands around the keyboard for odd bits of punctuation) than the "sensible" way to do it:

    tr '\0' '\n' < /proc/$pid/environ
Re:Useful Perl one-liners (2013) by teddyh on Wednesday November 30, 2016 @12:18AM (#13068661)
I prefer this, which is shorter than both of those:

    xargs -0n1 < /proc/$pid/environ
Re:Useful Perl one-liners (2013) by EvilTerran on Wednesday November 30, 2016 @04:52AM (#13069543)
Oh, nice! I always forget that xargs defaults to echoing the parameters if you don't specify a command.

That said, variations on my one are also handy for doing any further processing on the lines - eg, I do stuff like this pretty regularly:

    perl -ln0e '/^FOO=/&&print' /proc/$pid/environ
Re:Useful Perl one-liners (2013) by Gorgor on Tuesday November 29, 2016 @08:02PM (#13067622)
Could you explain that a bit more?
Re:Useful Perl one-liners (2013) by EvilTerran on Wednesday November 30, 2016 @04:40AM (#13069508)
Certainly! That expands to:

    perl -l -p -0 -e 1 /proc/$pid/environ
-l [octnum] is "automatic line-ending processing": it means the "input record separator" ($/, which defaults to "\n") is automatically stripped from the end of lines as they're read in; and the "output record separator" ($\, defaults to nothing), which is automatically appended to anything you print(), is set - to the character with the given octal code if specified, otherwise to the current value of $/.

-p makes perl act like sed: the input (which can either be stdin or the files listed after the flags on the command-line) is read one-line-at-a-time into $_, and for each line, your program is run, then $_ is printed.

-0 [octnum] sets the input record separator - and with no following digits, it gets set to the null character, "\0".

-e [script] specifies the content of the script to run - in this case, "1", a very terse way of doing nothing.

So: read each null-terminated "line", strip off the trailing null character, do nothing, then print it with a trailing newline.

The sneaky part is the ordering of the flags:

-l does { $\ = $/ }, -0 does { $/ = "\0" }, and they're processed in order - so if -0 appeared before -l, it wouldn't work, you'd wind up with both record separators set to "\0";

"-l0" would mean "-l with 0 as its parameter", ie { $\ = "\0" }, so I need to stick something else (-p) in between them if I want to squash everything into one argument without changing the meaning;

and -e1 has to appear at the end, because -e eats the rest of the argument.