After all it is such a handy language we use every day, often do not realize the power on our fingertips. I list here five tips which may save you a lot of code and improve it's quality and sexiness.
by @str84word
Handle the last slash in path
Sometimes we ask the user to enter a path for the base directory on which we either build some path tree or look for executable. In this situation we can never know either user enters slash at the end of the path or not. Either way, this is really common problem, and often you can see different workarounds. Bash lets you handle this problem with merely one line of code.
E_NOARGS=86
E_BADARG=87
USR_PATH=$1 # => '~/go/'
USR_PATH="${USR_PATH%/}/" # => '~/go/' (same as if the input was '~/go')
if [ -d "${USR_PATH}" ]; then
SRC=${USR_PATH}src/ # => '~/go/src/'
BIN=${USR_PATH}bin/ # => '~/go/bin/'
PKG=${USR_PATH}pkg/ # => '~/go/pkg/'
if [ -d ${SRC} ] && [ -d ${BIN} ] && [ -d ${PKG} ]; then
echo "${USR_PATH} is a proper GOPATH repository."
else
exit E_BADARG
fi
else
exit E_NOARGS
fi
# ...
Clear the file content
You probably know that one can send data to /dev/null
when the output is not significant.
mv * ./src 2> /dev/null
But did you know that the reverse (sending /dev/null
output to the file) works as well ? In result we get an easy mechanism to clear logs and releasing some computation data. There is however shorter syntax for doing just that.
cat /dev/null > computation.log
: > computation.log # Same as above
> computation.log # Still same behavior
Check if a program exists on the $PATH
This one is fairly simple solution, yet somebody may try to reinvent the wheel and manually check the $PATH. Luckily the type
command with -p argument is returning either the path string (which evaluates to true in conditional expression) or nothing (which evaluates to false).
dep=java
if ! `type -p ${dep} > /dev/null`; then
echo "Sorry, you need ${dep} to run my app."
exit 1;
fi
Variable type and closure
The way to extract a variable to a child process, that most programmers stick to, is the export
method. Local scope is often handled by the local
keyword which delimiters a variable only to the local process. Also you can merely see bash scripts which are using constants. Well, there is only one keyword you need to remember, giving a solution to all of above problems and more, it is quite like panacea for bash variable manipulation. Creating a variable simply using the declare
is restricting it to the given scope, causing closure effect. Useful to remember is also: -x
for export, -r
(read-only) for constants, -a
for array, -i
for integers (behaves similar to let
but with further scope restriction, see the example).
foo () {
local let x=10/2
declare -i -r y=10/2 # => 5
}
access () {
foo
echo $x # => 5
echo $y # => (nothing)
}
Command substitution
This is powerful concept that often seems to be misunderstood. Those are kind-of anonymous blocks of code. The block evaluation output can be plugged in to a command. Command substitutions can be also assigned to a variable for later use. For an simple example, sending ls -ltr
trough the command substitution will result in a nice formatted ls
output echoed to stdin.
echo "$(ls -ltr)" # You need to escape the command substitution
# with quote, otherwise echo will eat newlines.
The wide used syntax for creating an command substitution is trough the backticks `...`
. Hover the $(...)
has superseded the backticks syntax as it comes with few benefits, one of which is nesting command substitutions. Let's try actually something fun, like signing a loop to a variable.
names=( 'Alice' 'Bob' 'Charlie')
listNames=$(for i in $(seq 0 $(expr ${#names[@]} - 1)); do
declare -i index=${i}+1
echo -n "${index}.${names[${i}]} "
done)
names=( 'Dave' 'Erin' 'Frank')
echo "Participants: ${listNames}" # => Participants: 1.Alice 2.Bob 3.Charlie
Command substitution is ideal tool for expending bash tool-set. You can plug outside scripts, programs written in any language, or assign a code from a file very easily.
fork_c=$(itoa 77) # Now $fork_c will execute the c program from
# ./ directory. You can test it by downloading
# a C code snippet from:
# https://paste.debian.net/1041904/
# Then compile it to the directory where your
# script lives:
# gcc -std=c99 itoa.c -o itoa
file_definition=$(<itoa.c) # Get content of the 'itoa' source code
self_definition=$(<$0) # Save the content of the scripts itself
Notice from ABS Guide: "Do not set a variable to the contents of a long text file unless you have a very good reason for doing so. Do not set a variable to the contents of a binary file, even as a joke." (bit=$(<itoa)
<< do not dare!)
Conclusion
Order is crucial to avoid needless complexity. I hope you now say to yourself, "Wow this dude have style" and then you stick with this thought any time you write bash again but where the 'dude' will be you this time :).
Your backticks aren't actually shown though, you would have to type them like so:
(2 ticks, space, 1 tick, dots, 1 tick, space, 2 ticks) to display:
`...`
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Yeah, that one was pretty problematic, thank you!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!

Reply !stop to disable the comment. Thanks!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @str84word! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word
STOP
Do not miss the last post from @steemitboard:
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @str84word! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word
STOP
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @str84word! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit