Bash and shell scripting tips and tricks - mhulse/mhulse.github.io GitHub Wiki
Use sed
to find/replace text in a file:
sed -i 's/EnableSendfile on/EnableSendfile off/i' /etc/httpd/conf/httpd.conf
If you need to be root, do this:
# Switch to `root` user and start in `/root`:
$ sudo -i
# Same as above, but no directory switch:
$ sudo -s
# Invoke login shell after switching user (resets most environment variables, providing a clean base):
$ sudo su -
# … or:
$ sudo su
# Same as above, more explicit:
$ sudo su - root
# ... or, to switch to another user account:
$ sudo su <user>
Semi colons are use when EOL is missing; if EOL exists, no semi colon is required.
When assigning, no spaces around the =
.
foo='baz'
echo $foo
When comparing, put spaces before and after the =
.
foo='baz';
if [ $foo = 'baz' ]
then
echo $foo
fi
var="$(fdisk -l)"
The above variable is only available to the current shell. If it's an environment variable, you can export it to descendant shells:
export VAR="$(fdisk -l)"
See: Thread: How can I redirect stdout to a variable
$ cd -
$ cd ~- # Eats the return value of the above.
This will let you change directory to your previous location in the file system. It’s and easy way switch back and forth between two directories.
Most of the time you don't want to maintain two separate config files for login and non-login shells — when you set a
PATH
, you want it to apply to both. You can fix this by sourcing.bashrc
from your.bash_profile
file, then puttingPATH
and common settings in.bashrc
.
To do this, add the following lines to
.bash_profile
:
if [ -f ~/.bashrc ]; then source ~/.bashrc fi
> Now when you login to your machine from a console .bashrc will be called.
Alternatively, you could make `.bash_profile` your main config file by adding this:
```bash
# Nothing to see here — Everything's in .bash_profile:
[ -n "$PS1" ] && source ~/.bash_profile
… to your .bashrc
file (thank you Bashstrap!)
Unfortunately, the default history length in OS X is 500
commands. That seems like a lot, but when you're running 50+ commands a day it can push older commands off the list pretty quickly. This is easily solved by setting the HISTFILESIZE
in your .bash_profile
file.
HISTFILESIZE=
Source: How to increase bash shell history length in OS X
Here's my current .bash_profile
:
# http://unix.stackexchange.com/questions/1288/preserve-bash-history-in-multiple-terminal-windows
# http://superuser.com/questions/137438/how-to-unlimited-bash-shell-history
# https://www.kernel.org/doc/man-pages/online/pages/man3/strftime.3.html
export HISTCONTROL=ignoredups:erasedups # No duplicate entries.
export HISTSIZE=100000 # Big BIG history.
export HISTFILESIZE=100000 # Big BIG history.
export HISTTIMEFORMAT="%a %h %d - %r " # Timestamp.
shopt -s histappend # Append to history, don't overwrite it.
# Save and reload the history after each command finishes:
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
From the $ man bash
:
If HIST‐FILESIZE is not set, no truncation is performed.
... and:
If the HISTTIMEFORMAT variable is set, time stamps are written to the history file, marked with the history comment character, so they may be preserved across shell sessions.
Some interesting info here:
Preserve bash history in multiple terminal windows
Better color/readability, put this in your .bash_profile
:
# http://noahfrederick.com/blog/2011/lion-terminal-theme-peppermint/
# http://osxdaily.com/2013/02/05/improve-terminal-appearance-mac-os-x/
# http://stackoverflow.com/questions/1550288/mac-os-x-terminal-colors
export PS1="\[\e[0;31m\]\u\[\e[0m\]@\[\e[0;32m\]\h\[\e[0m\]:\[\e[0;34m\]\w\[\e[0m\]\$ "
export CLICOLOR=1
export LSCOLORS=ExFxBxDxCxegedabagacad
alias ls='ls -GFh'
… Or, use the color theme from: Bashstrap.
Reload using $ source .bash_profile
.
It also helps to turn on all "Text" options under Preferences >
Settings >
[Theme] >
Text.
Within same section, click on the Window button and adjust the opacity/blur of the "Background" (click on "Color & Effects").
Here's a theme I like:
SSH -t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
# Create and edit text file on remote machine:
ssh -t -i ~/.ssh/foo.pem [email protected] vi /tmp/myfile.txt
# Run `top`:
ssh -t -i ~/.ssh/foo.pem [email protected] top
Here's a bash alias used to restart Apache on a remote machine:
# Restart Apache (Unbuntu):
restart-foo='ssh -i ~/.ssh/foo.pem [email protected] sudo service apache2 restart'
Traverse entire machine to find a file name:
$ sudo find / -name "Xcode"
sudo
will suppress barking when trying to read directories where your ordinary login wouldn't have adequate privileges.
/
starts the search at the machine root and starts working its way down.
An alternative to find
(above) is locate
.
$ locate
usage: locate [-0Scims] [-l limit] [-d database] pattern ...
default database: `/var/db/locate.database' or $LOCATE_PATH
$ locate websitesoff403.html
WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.
$ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
Now, after the database has been built, you can do some fast searching of your local machine.
Find keyword in file:
$ grep -i error /etc/php.ini
This will print environmental variables "right now":
$ env
It shows you the useful ones, that you need need to know right now.
The ps (i.e., process status) command is used to provide information about the currently running processes, including their process identification numbers (PIDs):
$ ps
That will show you what unix shell you're using.
Hidden files:
$ sudo chmod -R g+w *.*
Everything else:
$ sudo chmod -R g+w *
Change user/group for everything in www/
:
$ sudo chown -R apache:apache www/*
Change group for .htaccess
file:
$ sudo chown apache:apache html/.htaccess
You could also:
$ sudo bash
... then just drop "sudo" from those other commands.
$ find ./directory -type f -exec chmod 0664 {} \;
$ find ./directory -type d -exec chmod 0755 {} \;