Live data from Hacker News

Ask HN: How can I get better at bash?

news.ycombinator.com

151–160 of 195 posts

Re: Ask HN: How can I get better at bash?

#151
post #13

How about you don't? Bash as scripting language is rather mediocre. Anything that is not simple in bash gets hard to read and debug and probably is wrong on some subtle levels. I have a rule of thumb that any shell script that grows beyond a screenful of lines gets redone in a proper scripting language.

There is this one case for which shell scripting is particularly interesting: dependencies simplification.

https://github.com/EtiennePerot/parcimonie.sh/blob/48044f913...

Re: Ask HN: How can I get better at bash?

#152
post #111

Earlier quoted context omitted.

I've heard this suggestion to use full paths for a long time. Why use full paths?

I'm sure there are other reasons, but the big one is that your scripts may get called in an environment other than your normal logged in shell. Cron, for example, doesn't have the same $PATH as your login shell. So no full paths means you can fail to run some commands, or run the wrong copy of one. There's also the security aspect. If your script has "." in it's $PATH, or something else writeable, I may be able to co…

This is terrible advice, if you expect your PATH to be something, just set it at the top of the script and be done with it.

No need to make it 100 times harder to read.

Re: Ask HN: How can I get better at bash?

#153
post #129

Earlier quoted context omitted.

Also CTRL-_ which is "undo whatever you just typed"

pressing CTRL-w a few times feels easier to me, less awkward key combination

CTRL-w just deletes a word at a time. CTRL-_ it appears doesn't just delete the whole line you just typed, it does undo of the thing you just typed... counting backspace as "one thing you just typed" -- so it does some things you can't achieve with CTRL+w, you can even get back some text that you just erased.

I never knew this shortcut before. (I will probably never use it...)

Re: Ask HN: How can I get better at bash?

#155

If you're not already familiar with it, I would suggest learning about the basic Unix process model -- fork, execve, wait, open, pipe, dup2 and friends. Bash is essentially a DSL for these. A lot of the weirdness you see in the language is due to these abstractions leaking through. For example: * Quoting is building execve's argv parameter. It's hard to quote correctly if you don't know what exactly you're working to…

What is a good learning resource for what the basic Unix process model (i.e. what you are describing?) Do you recommend a book or something like that? And preferably for a beginner?

Stevens - Advanced Programming in the Unix Environment

Love - Linux System Programming

The Unix-Haters Handbook

(Unfortunately, the best resource ever for this kind of stuff, from which I learned, does not have an English translation.)

Re: Ask HN: How can I get better at bash?

#156
Forget the Bash man page (just temporarily, that is) and read this:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3...

The POSIX specification of the Shell Command Language.

Also, don't overlook that there is a GNU Info manual for Bash, not just the manual page:

https://www.gnu.org/software/bash/manual/html_node/index.htm...

Re: Ask HN: How can I get better at bash?

#157
post #55

Earlier quoted context omitted.

In both my personal and professional life, I have the opposite conclusion. Bash is only for the simplest scripts and pipelines, and everything else (assuming you're going to use it more than once) gets written in Python or Go. The Bash syntax is not daunting, or if it is that's never been the problem with Bash. The problem is that Bash or shell programming in general gives you a million ways to shoot yourself in the…

> Like iterating over the files in a directory, for example. If you think that's easy in Bash you have either have a funny definition of easy Maybe I'm overlooking something...but why wouldn't this work: for file in $(ls); do { }; done

for file in *; do { ... }; done

is both much easier and much safer than piping the output of ls.

It does the correct thing with filenames containing spaces or weird characters, and the intent is much more visible, so there is really no reason to use $(ls).

More details: http://mywiki.wooledge.org/ParsingLs

Re: Ask HN: How can I get better at bash?

#158
As you're focused on the command line, I won't mention things I generally use in shell scripts like compound commands (if, for, while) or shell parameters. I will also skip things I don't often use.

First, there is moving around in bash - the arrow keys, or backspace/delete to remove a character, or ^A to go to line start, or ^R to search command history, or tab to complete a command. ^L clears the screen, although from habit I still type clear.

I use shell/bash builtins cd, and pwd often enough. Sometimes export, umask, exit, ulimit -a, echo.

I use shell variables like PS1, HOME, and PATH. I set them in $HOME/.bashrc, which sometimes references files like $HOME/.bash_aliases. I often set a larger than default history file size. I use ~ tilde expansion as an abbreviation for $HOME. For long commands I type regularly, I put an alias in the run control (or run control delegated) file.

I use job control commands like bg, fg, jobs and kill. You should know how bash job control complements and diverges from the system process commands. & starts a process as a background process, and preceding it from nohup tells it to ignore hangup signals.

You should know how single quotes work, and escape characters for them if they are needed.

Then there are pipes (| - "pipelines"), and redirecting of stdin, stdout, and stderr. I use this a lot. Also redirecting or appending output to a file (>, >>). I don't use tee often but sometimes do.

Then there are commands used with the shell a lot. Such as parallel, or xargs.

Also nice which modifies process scheduling.

Script, or typescript, keeps a log of your shell session.

Screen allows for multiple shell sessions. Useful on remote hosts especially (tmux is an alternative).

Then there are the standard file and directory commands I often use like pwd, cd, ls, mv, cp, df, chmod, du, file, find, locate, mkdir, touch, rm, which, and wc.

I manipulate these with commands like awk, sed, tr, grep, egrep, cat, head, tail, diff, and less.

I edit with vim or emacs -nw.

Command like htop, ps, w, uptime and kill let me deal with system processes.

Then there are just handy commands like bc or cal if I need to do some simple addition or see which day of the week the first of the month is.

Man shows you manual pages for various commands. "man command" will show the manual page. For a command like kill, the default will show the command kill - "man kill" which specifically is "man 1 kill". But "man 2 kill" would show the kill system call. You can see what these different manual sections are with "man man" - 1 is executable programs, 2 is system calls etc.

All of it is a process. I mentioned awk. It is one of the commands handy to use with the shell. I have seen entire programs written in awk. Some parts of awk I can use from memory, some I use occasionally and have to look up the flags to refresh my memory, some parts I have never used at all. As time goes on you pick up more and more as you need it.

Re: Ask HN: How can I get better at bash?

#159
post #111

Earlier quoted context omitted.

I'm sure there are other reasons, but the big one is that your scripts may get called in an environment other than your normal logged in shell. Cron, for example, doesn't have the same $PATH as your login shell. So no full paths means you can fail to run some commands, or run the wrong copy of one. There's also the security aspect. If your script has "." in it's $PATH, or something else writeable, I may be able to co…

This is terrible advice, if you expect your PATH to be something, just set it at the top of the script and be done with it. No need to make it 100 times harder to read.

Why even expect binaries to be in the same place on different systems with different default PATHs? Know how many times I've seen problems caused by (#!/usr/bin/bash|#!/bin/bash) pointing to the wrong place?

After reading this thread though, I'm not sure I want to suggest people write `#!/usr/bin/env bash` either... since that depends on the path being correctly set, and bash being in the path!

Re: Ask HN: How can I get better at bash?

#160
post #111

Earlier quoted context omitted.

I'm sure there are other reasons, but the big one is that your scripts may get called in an environment other than your normal logged in shell. Cron, for example, doesn't have the same $PATH as your login shell. So no full paths means you can fail to run some commands, or run the wrong copy of one. There's also the security aspect. If your script has "." in it's $PATH, or something else writeable, I may be able to co…

This is terrible advice, if you expect your PATH to be something, just set it at the top of the script and be done with it. No need to make it 100 times harder to read.

A PATH, though, is global.

Situations exist where you need more granularity.

There's also things like "watch" and "at" you might use in a shell script. They don't inherit the parent's environment, so setting PATH doesn't help.

You're correct in that "full paths" isn't a definitive answer though. I suppose the more generic advice to not depend on your environment to have it right is better.

Post reply on HN