Home
Main website
Display Sidebar
Hide Ads
Recent Changes
View Source:
BashNotes
Edit
PageHistory
Diff
Info
LikePages
!! What's true and what's false? 0 is true, anything non-zero is false. You can test the return value of any command by examining the special <tt>$?</tt> EnvironmentVariable. <pre> __$ ls mbox ; echo $?__ mbox 0 __$ ls mboxxx ; echo $?__ ls: mboxxx: No such file or directory 1 </pre> There are also special commands called true(1) and false(1) that can be used in tests: <pre> __$ true ; echo $?__ 0 __$ false ; echo $?__ 1 </pre> !! How do I stop bash beeping at me all the time? It's probably not bash(1) beeping, but readline(3) sending a bell. You can disable this by putting: <verbatim> set audible-bell none </verbatim> in your <tt>~~/.inputrc</tt> file. This will remove the bell for all readline(3) enabled programs. To make it only do this for bash(1), see the readline(3) section of the bash(1) manpage. If you are in a graphical environment, you can tell your [XServer] to disable all beeps for X programs (including xterm(1) and other terminals) by setting the bell volume to zero: <verbatim> xset b 0 </verbatim> If you use gnome, then that annoying beeping can be disabled by going to System > Preferences > Sound Find the "System Beep" tab and uncheck "Enable System Beep". !! How do I do arithmetic in bash? Surround the expression with $(( )), eg: <verbatim> ANSWER=$((6*9)) </verbatim> This is equivalent to using the expr(1) program, but you will need to escape any shell special characters: <verbatim> ANSWER=`expr 6 \* 9` </verbatim> !! How do I wait until a specified time? You could use at(1) but it's more fun to use something like this: <verbatim> sleep $(($(date -d '6pm tomorrow' +%s)-$(date +%s))) </verbatim> !! What's << doing in all my files? See HereDocuments. !! How can I easily do a batch rename of files with a subtle change (ie . to -)? Easy: <verbatim> for i in *.files.foo; do mv $i ${i/files.foo/files-foo}; done </verbatim> This lets you use sed(1)-like regexp syntax in the command line. You might want to read up on "Parameter Expansion" in bash(1). To remove a suffix: <verbatim> for i in *.files.foo; do mv $i ${i%.foo}; done </verbatim> To remove a prefix: <verbatim> for i in files-foo*; do mv $i ${i#files-}; done </verbatim> !! How do I get a sequence of numbers For small ranges you can just write the numbers out: <verbatim> for i in 2 3 4 5 6; do echo $i; done </verbatim> On [GNU] systems, use the <tt>seq(1)</tt> program: <verbatim> for i in `seq 50 1000`; do echo $i; done </verbatim> [FreeBSD] has a similar program called <tt>jot</tt>. !! How do I insert a Tab character when <tt>\t</tt> won't work? Type Ctrl-V so the next character will be interpreted literally, then tap Tab to insert a literal Tab character. !! How does redirection work? You can redirect a program's stdout and/or stderr to places other than the terminal – eg to files on the disk, or as another program's stdin. The order that redirections happen can be important. Some examples. Make stderr go to stdout, so you can view both of them together in less(1) or more(1): <verbatim> somecommand 2>&1 | less </verbatim> Get rid of stdout, and move stderr to stdout so that you can pipe it to less: <verbatim> somecommand 2>&1 >/dev/null | less </verbatim> The following first sends stdout to <tt>/dev/null</tt>, and then sends stderr to where stdout is now pointing (ie sends both to <tt>/dev/null</tt>, which is probably not what you want for redirection, but it's excellent for getting silent output from a command): <verbatim> somecommand >/dev/null 2>&1 </verbatim> As an alternative, to send both stdout and stderr to the same place you can use the <tt>&></tt> redirector: <verbatim> somecommand &>/dev/null </verbatim> See CshProgrammingConsideredHarmful for some trickier examples. !! How does redirection work from inside a script? A useful method to debug bash scripts is to run then with <tt>bash -x</tt>; printing each line as it goes, interspersed with its output. However, you can't start a script with <verbatim> #!/bin/bash -x > foo </verbatim> You can, however, do this: <verbatim> #!/bin/bash -x exec 1> /tmp/foo exec 2>&1 </verbatim> !! How can I get the output from a command into a program that acts on files, not stdin? Using process substitution (see [bash(1)Part4]) - <verbatim> gedit <(groff-2-wiki.pl bash) </verbatim> This opens up the bash(1) wikified page in gedit (as a temp file like <tt>/dev/fd/63</tt>), ready to manually overview and paste into the wiki. See the file archive for the groff-2-wiki script. !! Bash isn't using the full width of the terminal after I resize it When you resize a terminal, it sends a [SIGWINCH] signal to the process running inside it. If the current foreground process is not bash(1), but another process (eg less(1), tail(1), or whatever), then only that process receives the signal. The shell is then left with outdated size information. The best way to fix this is to set the <tt>checkwinsize</tt> shell option: <verbatim> shopt -s checkwinsize </verbatim> Bash will now check the size every time it displays a prompt. Other shells (such as zsh(1)) seem to do this automatically, and don't have a corresponding option. A one-off workaround is to send [SIGWINCH] to the shell yourself: <verbatim> kill -WINCH $$ </verbatim> (<tt>$$</tt> is a variable containing the shell's own [PID].) !! How do I change the title of a terminal? From [faqs.org|http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#ss4.3]: Window and icon titles may be changed in a running xterm(1) (and most derivatives, such as gnome-terminal) by using XTerm escape sequences. The following sequences are useful in this respect: * <tt>''ESC'']0;string''BEL''</tt> – Set icon name and window title to string * <tt>''ESC'']1;string''BEL''</tt> – Set icon name to string * <tt>''ESC'']2;string''BEL''</tt> – Set window title to string where ESC is the escape character (\033), and BEL is the bell character (\007). <verbatim> echo -ne "\033]0;''title here''\007" </verbatim> In bash(1), to have the title automatically update based on who and where you are, set <tt>PROMPT_COMMAND</tt> like so: <verbatim> ROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"' </verbatim> !!How do I enable case-insensitive tab completion? * bind "set completion-ignore-case on" That should configure the shell completion to be case-insensitive for the remainder of the session. Make permanent: Create a file called .inputrc in your home directory and put this line in it: *set completion-ignore-case on !! Help, bash is listing my files weird! Well, bash is listing nothing. It's ls(1) and its locale support that matter here, it has nothing to do with the [Shell]. But this is where you'd expect to find this tidbit. I swear ls(1) used to list files in [ASCII] order. Then one day it stopped. And I didn't like it. Much swearing and cursing ensued. <verbatim> $ ls -la total 3612 drwxr-xr-x 15 573 573 4096 2005-05-14 14:53 . drwxrwsr-x 4 root src 4096 2005-06-15 01:59 .. drwxr-xr-x 20 573 573 4096 2003-08-25 23:44 arch -rw-r--r-- 1 root root 17644 2005-05-14 14:44 .config -rw-r--r-- 1 root root 4376 2005-05-14 14:46 .depend -rw-r--r-- 1 573 573 18691 2002-08-03 12:39 COPYING drwxr-xr-x 32 573 573 4096 2005-04-04 13:42 Documentation drwxr-xr-x 40 573 573 4096 2005-05-14 14:45 drivers -rw-rw-r-- 1 573 573 19095 2005-05-14 14:44 Makefile drwxr-xr-x 2 573 573 4096 2005-05-14 14:49 mm -rw-r--r-- 1 573 573 14287 2003-08-25 23:44 README -rw-r--r-- 1 root root 505139 2005-05-14 14:53 System.map -rw-r--r-- 1 root root 2 2005-05-14 14:46 .version -rwxr-xr-x 1 root root 2646164 2005-05-14 14:53 vmlinux $ export LANG=C LC_ALL=C $ ls -la total 3612 drwxr-xr-x 15 573 573 4096 May 14 14:53 . drwxrwsr-x 4 root src 4096 Jun 15 01:59 .. -rw-r--r-- 1 root root 17644 May 14 14:44 .config -rw-r--r-- 1 root root 4376 May 14 14:46 .depend -rw-r--r-- 1 root root 2 May 14 14:46 .version -rw-r--r-- 1 573 573 18691 Aug 3 2002 COPYING drwxr-xr-x 32 573 573 4096 Apr 4 13:42 Documentation -rw-rw-r-- 1 573 573 19095 May 14 14:44 Makefile -rw-r--r-- 1 573 573 14287 Aug 25 2003 README -rw-r--r-- 1 root root 505139 May 14 14:53 System.map drwxr-xr-x 20 573 573 4096 Aug 25 2003 arch drwxr-xr-x 40 573 573 4096 May 14 14:45 drivers drwxr-xr-x 2 573 573 4096 May 14 14:49 mm -rwxr-xr-x 1 root root 2646164 May 14 14:53 vmlinux </verbatim> !! Dealing with argument lists in wrappers If you have a shell script that passes arguments on to another program while acting as a wrapper watch carefully how you deal with arguments or you will end up accidentally eating whitespace. See the example below for a demonstration. <tt>test.sh</tt>: <verbatim> #!/bin/bash # Print number of arguments echo $# </verbatim> <tt>wrapper.sh</tt>: <verbatim> #!/bin/bash # Do some stuff here # Call another program ./test.sh $@ </verbatim> <tt>safe_wrapper.sh</tt>: <verbatim> #!/bin/bash # Do some stuff here # Call another program ./test.sh "$@" </verbatim> <tt>Output</tt>: <verbatim> matt@argon:/tmp$ ./wrapper.sh 0 matt@argon:/tmp$ ./safe_wrapper.sh 0 matt@argon:/tmp$ ./wrapper.sh a 1 matt@argon:/tmp$ ./safe_wrapper.sh b 1 matt@argon:/tmp$ ./wrapper.sh a "" 1 matt@argon:/tmp$ ./safe_wrapper.sh b "" 2 </verbatim> Note that the 'empty' argument is only preserved when $@ is wrapped in quotes (eg in safe_wrapper.sh). !! Why can't I hit ''Del''? Why does it show a tilde (~~) character ? readline(3) isn't correctly interpreting the escape code that delete generates. You can work around it in your terminal, but the easiest fix is to add the line <verbatim> "\e[3~": delete-char </verbatim> to <tt>~~/.inputrc</tt>. Garret ~LeSage has posted a [super useful inputrc|http://linuxart.com/log/archives/2005/10/13/super-useful-inputrc/], which fixes all sorts of keys (such as ctrl-arrow). Here's another cool self-documented tip: <verbatim> # By default up/down are bound to previous-history # and next-history respectively. The following does the # same but gives the extra functionality where if you # type any text (or more accurately, if there is any text # between the start of the line and the cursor), # the subset of the history starting with that text # is searched (like 4dos for e.g.). # Note to get rid of a line just hit Ctrl-C. "\e[B": history-search-forward "\e[A": history-search-backward </verbatim> !! How do I feed quote characters to the other end of an [SSH] session? I have a bunch of remote machines with a config file that has some <tt>OPTIONS=something</tt>, and I want to set them all across-the-board to <tt>OPTIONS="foo"</tt>. Locally, I would do it this way: <verbatim> sed -i -e 's/OPTIONS=.*/OPTIONS="foo"/' file </verbatim> This is hard to send over [SSH] however, as bash(1) locally likes to eat all your quotes, so they never reach the other end. PerryLorier's most bodacious answer: <verbatim> ssh site sed -i -e \''s/OPTIONS=.*/OPTIONS="foo"/'\' file </verbatim> If anyone else has an answer, please add it, rather than replacing this one; I can at least understand what happens here. One set of brackets is eaten locally, and another set is sent to the other end, so the sed command ends up with 's when run on the remote host. —CraigBox Another option: <verbatim> ssh site <<'END_SCRIPT' sed -i -e 's/OPTIONS=.*/OPTIONS="foo"/' file END_SCRIPT </verbatim> —AristotlePagaltzis LawrenceDoliveiro's so-simple-you'll-kick-yourself-for-not-thinking-about-it answer: <verbatim> ssh site sed -i -e $(printf %q 's/OPTIONS=.*/OPTIONS="foo"/') file </verbatim> using Bash's <tt>printf</tt> builtin. !How can I see what my command will look like after bash expands it? After typing the command, press ''Esc'' then press ''C-e'' !Bash C-style for loop construct for ((i=1; i<100;i++));do echo $i; done; !How can I do Division in bash using floating point numbers? Use ''bc'' *echo "scale=10;5/4" | bc" will result in : 1.2500000000 The value of the scale function is the number of digits after the decimal point in the expression. (In this case 10) !How Can I use ''and'' / ''or'' in bash if statements? *You can do boolean OR in BASH by using the -o operator. *You can do boolean AND in BASH by using the -a operator. Try intermixing the two also. <verbatim> if [ $bla -eq 1 -o $cars -eq 3 -o $monkeys -eq 4 ]; then echo "Westside" fi </verbatim> !How can I supply filenames with a prefix of '-' '--' as arguments to a program? Say you have a file called '--test'. If you wanted to use vim to edit this file then you would do: <verbatim> vim -- --test </verbatim> The '--' tells the command that what follows is an argument, NOT to interpret them as options. AdrianHo: Note that not all programs accept '--' as an "end of options" marker. A more reliable method is prefixing the filename with "./", as in: <verbatim> vim ./--test </verbatim> !How to directly interpret a shell script by the current shell. (Without forking a subshell) *. <myscript> If the above script makes a change to the environment, it is the environment of this shell that is changed. So if inside the script we change the directory, then when the script has finished being interpreted we will find ourselves in the new directory. Note : This can be handy when you want to reset the shell environment variables. Just do: *. ~~/.bashrc !Set vi mode in bash Vi mode allows for the use of vi like commands when at the bash prompt. When set to this mode initially you will be in insert mode (be able to type at the prompt unlike when you enter vi). Hitting the escape key takes you into command mode. To enable this do: *set -o vi One thing I do like about vi mode, is how easy it is to edit really long commands. (Of course some will argue that I should just use a bash script instead) When in ''vi mode'' press 'esc' to enter ''command mode''. Now press 'v'. This will start up the default editor (as defined by the EDITOR environment variable) and your command will be displayed. Edit it to your liking (feel free to use multiple lines for loops/if statements etc), save and exit. Your command will be executed. To escape out of ''vi mode'' simply type: *set +o vi !! See also * CommonErrors, under "Your shell hangs" * BashOneLiners * SpacesInPathNames * PortabilityNotes * BashHistory * [bash reference manual|http://www.gnu.org/software/bash/manual/bashref.html] ---- CategoryNotes
4 pages link to
BashNotes
:
InNeedOfRefactor
SpacesInPathNames
Shell
UserSubmittedNotes