Set your shell options to something useful

September 7th, 2009 by tburns

You can manipulate shell options to allow for more useful and intuitive function using the shopt command.

Copying Files:

In Fedora, by default, wildcard options with some file manipulation commands such as cp, mv, and rm will not copy the hidden files in the present working directory. This is because file globbing (pattern matching) is not set to expand hidden files. Suppose, for example, I wanted to copy the entire contents of this user’s directory to another location. The directory has a listing of files, both hidden and not hidden, as well as one subdirectory called documents/. Here is the output of a recursive listing showing all the files in the tree:

 [sshuser@localserver ~]$ ls -alR
.:
total 40
drwx------  3 sshuser sshuser 4096 2009-09-07 11:02 .
drwxr-xr-x 12 root    root    4096 2009-09-06 13:16 ..
-rw-------  1 sshuser sshuser  490 2009-07-29 12:20 .bash_history
-rw-r--r--  1 sshuser sshuser   18 2008-02-29 08:27 .bash_logout
-rw-r--r--  1 sshuser sshuser  176 2008-02-29 08:27 .bash_profile
-rw-r--r--  1 sshuser sshuser  124 2008-02-29 08:27 .bashrc
-rw-r--r--  1 sshuser sshuser 7023 2009-09-07 11:02 code-markup.php
drwxr-xr-x  2 sshuser sshuser 4096 2009-09-07 11:03 files
-rw-r--r--  1 sshuser sshuser  920 2009-09-07 11:02 traffic.dmp

./documents:
total 8
drwxr-xr-x 2 sshuser sshuser 4096 2009-09-07 11:03 .
drwx------ 3 sshuser sshuser 4096 2009-09-07 11:02 ..
-rw-r--r-- 1 sshuser sshuser    0 2009-09-07 11:02 .file-1.txt
-rw-r--r-- 1 sshuser sshuser    0 2009-09-07 11:03 resume.doc
[sshuser@localserver ~]$


Using the cp command with the archive and verbose output options, will not copy the hidden files in the present working directory, but will copy the hidden files in the documents/ directory. (This is because the files in the documents/ directory do not start with the ‘.’ as the files in the present working directory do. Instead, their absolute file names are all prepended with documents/):

 [sshuser@localserver ~]$ cp -av * /opt/directoryBackups/
`code-markup.php' -> `/opt/directoryBackups/code-markup.php'
`documents' -> `/opt/directoryBackups/documents'
`documents/resume.doc' -> `/opt/directoryBackups/documents/resume.doc'
`documents/.file-1.txt' -> `/opt/directoryBackups/documents/.file-1.txt'
`traffic.dmp' -> `/opt/directoryBackups/traffic.dmp'
[sshuser@localserver ~]$

To allow this command to copy all the files in the entire tree, set your shell options to expand dot files via the use of globbing:

 [sshuser@localserver ~]$ shopt -s dotglob
 [sshuser@localserver ~]$ shopt dotglob
dotglob        	on
[sshuser@localserver ~]$

This sets the dotglob option to ‘on’ and will then allow you to grab all the hidden files in the present working directory too:

 [sshuser@localserver ~]$ cp -av * /opt/directoryBackups/
`.bash_history' -> `/opt/directoryBackups/.bash_history'
`.bash_logout' -> `/opt/directoryBackups/.bash_logout'
`.bash_profile' -> `/opt/directoryBackups/.bash_profile'
`.bashrc' -> `/opt/directoryBackups/.bashrc'
`code-markup.php' -> `/opt/directoryBackups/code-markup.php'
`documents' -> `/opt/directoryBackups/documents'
`documents/resume.doc' -> `/opt/directoryBackups/documents/resume.doc'
`documents/.file-1.txt' -> `/opt/directoryBackups/documents/.file-1.txt'
`traffic.dmp' -> `/opt/directoryBackups/traffic.dmp'
[sshuser@localserver ~]$

To set this option for each session, put this command in your .bashrc file.

 [sshuser@localserver ~]$ shopt -s dotglob 

Maintaining All Your History Commands:
The shopt command when run without any options displays all the set or unset shell options available to the user. One of those, the histappend option is unset by default as well. This is a useful one, though, especially for those of us who use multiple terminals and multiple sessions concurrently. Whenever you exit a session, your command line history is written to whatever the user’s history file is. In Fedora, by default, users are created with bash as their shell, meaning that .bash_history is the user’s history file. You can check this by echoing the shell variable:

 [sshuser@localserver ~]$ echo $HISTFILE
/home/sshuser/.bash_history 

As I said, your history is appended to your history file on session exit. However, if you have several sessions running at the same time, you can lose history because none of your session commands are written to the history file until the session closes. You run the risk then of overwriting history because your shell option is set to overwrite, not append. To fix this, use shopt to set your history to append to your history file each time a session is closed.

To set this option for each session, put this command in your .bashrc file.

 [sshuser@localserver ~]$ shopt -s histappend 

There is also the option of writing to the history file in real time for each session. In other words, each time you execute a command in any shell, that command is written to your history. The only reason I don’t use this, is because my history file will then be out of order of the execution history. I will have a jumble of commands then, rather than a neat, ordered listing that I can go back and review or from which I can execute the last specific command. For example, if I want to re-execute the last find command, I can type !find. If, however, if I have overwritten my .bash_history with other find commands from other sessions, I can’t trust that the last one in the file is the one I want.. If you want this real-time append option though, you can add to your session $PROMPT_COMMAND variable. Just add this to your .bashrc file along with the shopt command:

[sshuser@localserver ~]$ PROMPT_COMMAND="history -a:$PROMPT_COMMAND"

Of course, any time you add to your .bashrc file (or .bash_profile file, for that matter) be sure to source the file again to make those changes current:

[sshuser@localserver ~]$ source .bashrc
  • Share/Bookmark

One Response to “Set your shell options to something useful”

  1. Joyce says:

    Extremely useful post! Thank you!

Leave a Reply