Live data from Hacker News

Unix Commands I Abuse Every Day

everythingsysadmin.com

61–70 of 108 posts

Re: Unix Commands I Abuse Every Day

#61

Earlier quoted context omitted.

find ./ -name '*.log' | xargs rm Only do that if you know exactly what '*.log' will expand to (i.e. don't use it in scripts and avoid using it on the command line). This is because the delimiter for xargs is a newline character, but filenames can have a newline character in them. This can lead to unexpected results. Almost everywhere I see xargs used, find ...-exec {} ; will work as well and find ...-exec {} + may wo…

find ./ -name '*.log' -print0 | xargs -0 rm Fixes that issue and xargs is far more efficient, it doesn't launch a new process for each line like exec does, but far more importantly, xargs is generalizable to all commands so you only have to learn it once; exec is just an ugly hack on find, you can't generalize it across all commands; xargs is much more unixy.

> it doesn't launch a new process for each line like exec does

Exec doesn't either if you use "+" as a terminator:

    find . $(options) -exec command {} \;
executes one command per match,

    find . $(options) -exec command {} +
executes a single command with all matches

> exec is just an ugly hack on find

Obvious and complete nonsense, -exec is both an important predicate of find and a useful and efficient tool.

-print0/xargs -0, now that is a hack.

Re: Unix Commands I Abuse Every Day

#62
post #23

Earlier quoted context omitted.

It'll save you a few more keystrokes if you do cat !$ | less !$ is "the last argument to the previous command".

If you do less . it will save you even more keystrokes.

Do you remap ESC to another key?

Re: Unix Commands I Abuse Every Day

#63
post #2

My #1 abuse is xargs -n1. A lot of people like writing bash for loops, I will try and avoid that as much as possible, xargs -n1 is the bash equivalent of a call to 'map' in a functional language. For instance, let's say you want to create thumbnails of a bunch of jpegs: find images -name "*.jpg" | xargs -n1 -IF echo F F | sed -e 's/.jpg$/_thumb.jpg/' | xargs -n2 echo convert -geometry 200x Additionally, it's fully pa…

Why do that when a loop is clearer, safer, and shorter? find images -name '*.jpg' | while read jpg; do convert -geometry 200x "$jpg" "$(echo "$jpg" | sed 's/.jpg$/_thumb.jpg/')"; done This version works even when there are spaces in a filename, whereas yours will break.

an alternative approach

   echo images/*.jpg|sed 's/.*/convert -geometry 200x \"&\" \"&_thumb.jpg\"/;s/\.jpg_thumb/_thumb/' > script; sh -v script 2>log
you could also use -x instead of -v

reasoning:

globbing is as fast as find and is faster than find _if_ you do the same glob twice (b/c it's cached); i'm assuming the images dir is not full of subfolders otherwise i would would do

   echo images/*/*
if the dir structure gets any deeper than 2 levels, i'd use find

while loops typed from the command line are a p.i.t.a. if you don't bg them initially and want to bg them later; you need to put them inside brackets or into a function

using a script and a log, if something goes wrong while it's running, you can restart after looking at the log; you can't do that with a loop

Re: Unix Commands I Abuse Every Day

#64
post #11
post #6

Random note. The most commonly "abused" Unix command is cat. The name is short for "concatenate", and its intended purpose was originally to combine 2 or more files at once. Therefore every time you use it to spool one file into a pipeline, that is technically an abuse!

I have long thought that some sort of zsh completion that detects that abuse of cat and converts it into the more appropriate `< file` might be a good idea. If it did it silently it probably wouldn't be worth it but if it actually preformed the substitution in front of you then it might help users get more comfortable with the carrot syntax.

Interestingly, there are some circumstances where you actually want "cat file | program" and not "program < file". The case I have in mind is when file is actually a named FIFO which was not opened for writing. If you use cat, program will still run and only reads to stdin will block (but it can perform other things, possibly in different threads). If you use '<', opening stdin will block and program will probably block altogether.

Re: Unix Commands I Abuse Every Day

#66
post #2

My #1 abuse is xargs -n1. A lot of people like writing bash for loops, I will try and avoid that as much as possible, xargs -n1 is the bash equivalent of a call to 'map' in a functional language. For instance, let's say you want to create thumbnails of a bunch of jpegs: find images -name "*.jpg" | xargs -n1 -IF echo F F | sed -e 's/.jpg$/_thumb.jpg/' | xargs -n2 echo convert -geometry 200x Additionally, it's fully pa…

Why do that when a loop is clearer, safer, and shorter? find images -name '*.jpg' | while read jpg; do convert -geometry 200x "$jpg" "$(echo "$jpg" | sed 's/.jpg$/_thumb.jpg/')"; done This version works even when there are spaces in a filename, whereas yours will break.

Even shorter, avoiding the echo sed business:

  find images -name '*.jpg' | while read jpg; do
      convert -geometry 200x "$jpg" "${jpg%%.jpg}_thumb.jpg";
  done

Re: Unix Commands I Abuse Every Day

#67
post #6

Random note. The most commonly "abused" Unix command is cat. The name is short for "concatenate", and its intended purpose was originally to combine 2 or more files at once. Therefore every time you use it to spool one file into a pipeline, that is technically an abuse!

I've sometimes heard it's "catenate" not "concatenate".

Do they mean the same thing?

As for cat, the utility, I'm afraid we'll never stop seeing people doing

   cat file|prog1|prog2
even when it makes absolutely no sense whatsoever.

If it did, I might as well do

   cat file|cat|prog|cat|prog2|cat -
I mean, why not? It "looks nicer" than

   prog file|prog2 or 
   prog 
Programmers love their cats.

Re: Unix Commands I Abuse Every Day

#68
post #60

Earlier quoted context omitted.

Why do that when a loop is clearer, safer, and shorter? find images -name '*.jpg' | while read jpg; do convert -geometry 200x "$jpg" "$(echo "$jpg" | sed 's/.jpg$/_thumb.jpg/')"; done This version works even when there are spaces in a filename, whereas yours will break.

false $ ls -Ql totale 4 -rw-r--r-- 1 zed users 33 set 6 07:30 " spaces " $ $ find -name '*spaces*' | while read text; do cat "$text"; done cat: ./ spaces: File o directory non esistente $ $ find -name '*spaces*' -print0 | xargs -0 cat while read is broken with spaces $

Only for file names starting or ending with spaces, as far as I can tell, which are pretty unusual.

Re: Unix Commands I Abuse Every Day

#69
post #6

Random note. The most commonly "abused" Unix command is cat. The name is short for "concatenate", and its intended purpose was originally to combine 2 or more files at once. Therefore every time you use it to spool one file into a pipeline, that is technically an abuse!

It may be an abuse, but at least it has no influence on the correctness of the result as pipes are a monad http://okmij.org/ftp/Computation/monadic-shell.html

Re: Unix Commands I Abuse Every Day

#70
post #23

Earlier quoted context omitted.

If you do less . it will save you even more keystrokes.

Do you remap ESC to another key?

No, but for me acts like and the actual keybinding is M-. or M-_.

The command you are looking for is yank-last-arg for bash and insert-last-word for zsh.

Post reply on HN