Category Archives: Script
getopt is a command used in scripts to parse their options and add a basic error checking ability.
getopt is not
getopts the bash built-in that has similiar functionality. Urban Vagabond explains:
getoptsare different beasts, and people seem to have a bit of misunderstanding of what they do.
getoptsis a built-in command to bash [that] processes command-line options in a loop and assigns each found option and value in turn to built-in variables [(so that they can be further processed)].
getopt, however, is an external utility program, and it doesn’t actually process your options for you the way that [(e.g.)] bash getopts, the Perl Getopt module, or the Python optparse/argparse modules do. All that
getoptdoes is canonicalize the options that are passed in — (i.e. convert them to a more standard form) so that it’s easier for a shell script to process them.
For example, a use of getopt converts the following:
tmpscript -abd -ooutfile.txt
tmpscript -a -b -d -o outfile.txt
getopt can also process the long format option of
--output=/tmp.... Also basic error check abilities, it has:
tmpscript -c tmpscript: invalid option -- 'c'
tmpscript -o tmpscript: option requires and argument -- 'o'
getopt gets defined by telling it the available options in short and long form (if you like). An option with a colon (:) following denotes that an argument is required for that option. If followed by two colons the argument is optional. Here is an example:
Options are generally set as variables so that they can defined how to be used after the while loop (usually, so that mainly they are processed in the right order).
getopt parses in the same order as specified on the input, so a
-a -d -b input would not work real well if the
-d option required the
-b option to run correctly.
One caveat of
getopt is that each option allows either one or no arguments to follow. So in input like
tmpscript -v --files file1.txt file2.txt file3.txt just isn’t possible in any type of predictable-fashion. One can however use quotes on the input:
tmpscript -v --files "file1.txt file2.txt"
or use mutiple options (
-f file1.txt -f file2.txt) and append them to an array, as seen, here.
When I’m about to edit a configuration file or a bash script, sometimes I don’t know if the edit will work. In these cases I create a backup of it in numbered order (to keep track of them if I need to revert the changes). Because this is something I regularly do, I decided to build a script to make this easy. The usage is basic: define the file and destination-directory:
# bckfile definedfile.bash . ‘/home/johndoe/.local/bin/definedfile.bash’ -> ‘/home/johndoe/.local/bin/definedfile_00.bash’
Optionally a tag can be added too:
bckfile youdle .vault/ new ‘/home/johndoe/.local/bin/youdle’ -> ‘/home/johndoe/.local/bin/youdle_02-new’
A limitation of the script is that filename cannot have ‘periods’ in their filename. A heuristics of discovering multiple extensions and with . in the filename itself would be tough.
I am really lazy with my editors. I have aliases in my shell configuration for gedit and vim that are very basic:
alias v="vim -p" # open in tab alias sv="sudo vim -p" alias g="bgcmd gedit" alias sg="bgcmd gksudo gedit"
This is very nice for me because I use my editors quite a bit. One thing I needed though was a command that would create and open a temporary file in gedit. The main reason for this is that at the time I don’t know how to name or place the file properly. Another reason is that at other times I like to have a scratchpad but would lose information if it was just a New File and a crash… happened.
gt will create and open a file named of the current time (MMDDhhmm) and will be saved in the trash folder. If
gt is followed by a name (e.g.
gt cssbox or
cssbox.css) the name will be appended to the current time.
The name is helpful if wanting to dig the file out of the trash folder at a later time.
xuserrun is a bash script to run a command on the active X.org server display. This is primarily necessary if from within another environment (different user, console, cron, boot script…). xuserrun gathers DISPLAY and user environmental variables via systemd and passes them on to be able to dothis. xuserrun is designed for use with only a single user X.org server display. Running it is basic:
xuserrun xclock -digital
Tto put out a notification:
xuserrun notify-send "Hello, Dave."
When I first used
ln, I expected the behavior of
ln source link to work. But
ln is slightly more complicated than that. While learning it from the beginning, I discovered it does not always resolve the path correctly; additionally, it doesn’t not error if the source is non-existence. I discovered that this was necessary because
ln is designed to be versatile. So I understood that one would want links at times to be created that don’t exist yet, but it was unhelpful to me in the way that I felt
ln should logically work, and the way that I wanted to use it.
Originally, I would do a link like this and it would be broken:
# ln -s ../dir/file dir/
I’ve attempted other links since then that too (of which I can’t remember now) would also be broken. So the way I discovered to do links correctly without doubt was to use whats called the fully-qualified or absolute path (i.e. a path defined from root [
# ln -s /home/username/Document/file /home/username/Desktop/file
There’s a program called
realpath that does this, so I wrote a wrapper script for it and it turned out to be pretty easy. The script resolves the absolute paths, verifies the existence of the source directory and link parent directory, and detects write permissions prompting sudo when needed. It works like this:
# lnk ~/Documents/Resumes/ ~/Desktop ‘/home/username/Documents/Resumes’ -> ‘/home/username/Desktop/Resumes’
# lnk ~/Documents/Resumes/ ~/Desktop/Resumes-I-like ‘/home/username/Documents/Resumes’ -> ‘/home/username/Desktop/Resumes-I-like’
a specifically named link will be put on the Desktop.
# lnk /etc/fstab ~ # or use ~/fstab-edit ‘/etc/fstab’ -> ‘/home/todd/fstab’
If trying to link to a write-protected directory:
# lnk /usr/share/vim/vim73/vimrc_example.vim /etc/vimrc [sudo] password for $USER: ‘/usr/share/vim/vim73/vimrc_example.vim’ -> ‘/etc/vimrc’
An error message will appear if the source or link parent directory doesn’t exist:
* The script will work for just about any instance with the exception of removable media where relative-paths would be better used.
I use my laptop primarly at home with an external monitor as discrete, meaning that I have the laptop monitor turned off and I only use it. At times this is also called a dedicated monitor. GNOME can be set to disable the laptop monitor and enable the external but it wasn’t able to hotplug the monitor after I returned the laptop, and at times wouldn’t do so after resuming from sleep. Also in the proccess I discovered that the X.org server DPI setting wasn’t being done correctly and that GNOME’s text scaling needed to be adjusted. So I decided to do it in a script and it turned out to be pretty easy.
I wrote the basic script that toggles monitors depending if the external monitor is present, then it detects correct physical size dimension of the screen so the the correct DPI can be set. After this, I added a startup script (.desktop file), a pm-utils script to runafter resuming, and a udev script to detect andset the monitor when plugged in. The udev rule is generic but appears to be working for a lot of people, it relys on Kernel Mode setting (KMS) so doesn’t work for me wiht the catalyst driver, but every thing else works great. I put it on github for any who like to look at it.
The bash script cannot be used right away instead a couple bit will need to be directed:
The package cannot be installed directly and be expected to work, some edits will need to be made. First, in the resume script '80_discretemon' a username will need to be defined; next, the monitor names will need to be defined as created by the driver in 'discretemon'.
Also, the monitors can be defined in
xorg.conf but the fix for after resume from sleep, remains.
Section "Monitor" Identifier "0-LVDS" Option "VendorName" "ATI Proprietary Driver" Option "ModelName" "Acer Aspire Laptop Screen" Option "DPMS" "true" Option "TargetRefresh" "60" Option "Position" "0 0" Option "Rotate" "normal" Option "Disable" "true" DisplaySize 344 194 # only works with xrandr disabled. EndSection Section "Monitor" Identifier "0-DFP1" Option "VendorName" "ATI Proprietary Driver" Option "ModelName" "Samsung SyncMaster SA350" Option "DPMS" "true" Option "PreferredMode" "1920x1080" Option "TargetRefresh" "60" Option "Position" "0 0" Option "Rotate" "normal" Option "Disable" "false" DisplaySize 476 268 # only works with xrandr disabled. Option "DPI" "102 x 102" EndSection
I got to test out a good number of screencasting applications and I found a good one, and as usual the easiest was the best. I started with recordMyDesktop.
recordMyDesktop is a basic program that works good. The GTK version has a simple UI that sets a border around the area to be recorded. I has sound recording too.
A minor thing but of note is that the window detection area is off when selecting a windows, but the reason I didn’t use recordMyDesktop was because I found the quality wasn’t that good. It could be because it uses
.ogv format, or perhaps it had something to do with my system.
This is and example I did with recordMyDesktop and though it’s enlarged (OpenShot doesn’t have the ability to use the original size) the quality I wanted to be better.
I tried Istanbul and a couple others all with about the same recording results. Istanbul hasn’t been developed in several years and though I got excited about xvidcap it hasn’t been developed in years either. xvidcap grabs screenshots and then concatenates them into a video. I got excited because xvidcap’s preview uses Imagemagick’s
animate tool to preview the video and it was real nice. Unfortunately very little works in xvidcap anymore but taking the screenshots. To put them together I used:
fmpeg -i out%04d.xwd -r 15 -vcodec huffyuv test.avi
unfortunately the quality was no better than that of the others.
The great command line tool to encode and decode video
ffmpeg can also do screencasts and I read a lot of how people liked it (and I do too). To use it it’s real basic:
ffmpeg -f x11grab -s wxga -i :0.0 -sameq screencast.mpg
The quality isn’t quite what I want it to be, but I’ve seen other people have nice looking screencasts so I think it must be either my video card or my video driver.
This line can be amended some for better quality, performance, and add sound recording. Using the raw, lossless codecs for video and audio improves processor usage for better FPS recording:
ffmpeg -f x11grab -s wxga -i :0.0 -vcodec huffyuv -sameq -acodec pcm_s16le -f alsa -i pulse -ac 2 screencast.avi
-iare for size and input.
-swill give the dimensions and
-iwill define the co-ordinates.
wxgais a definition of a video resolution standard (available ones are listed in
-rcan be added to define the frame rate. Default is 25 and is good. Only reason really to change it is if frames are dropped during recording (marked with red).
-follow_mouse 100can be added to follow mouse movements.
100is the border in pixels that must be reached before the area is moved.
ffcast and FFmpeg
ffcast is a program that grabs and passes X.org server dimensions and co-rodinates to other programs. It has built-in support to pass these parameters for some programs including
ffmpeg. So the command will now look like this:
ffcast -s ffmpeg -- -vcodec huffyuv -sameq -acodec pcm_s16le -f alsa -i pulse -ac 2 screencast.avi
-s option will prompt for the screen area and then pass the dimensions and co-orodinates to
Now to make this easy, I put this in a bash script, it runs as such:
screencast <a|f|m|w> - create screencasts (a)rea (f)ull-screen (m)ouse (w)indow
Here’s the bash script:
At times I like to check my levels of disk and memory usage and it’s more convenient for me to do it from the command line. So, I created a couple scripts for them:
devtop Filesystem Size Used Avail Use% Mounted on /dev/sda5 9.8G 6.4G 2.9G 69% / /dev/sda6 166G 38G 121G 24% /home
memtop PROGRAM %MEM #MEM firefox 10.2 352.98 MB gnome-shell 4.1 141.76 MB Xorg 1.5 53.60 MB nautilus 1.2 41.52 MB gedit 1.1 40.59 MB gnome-settings- 0.7 26.23 MB gnome-terminal 0.6 22.31 MB nm-applet 0.6 21.30 MB python2 0.6 20.89 MB
Saves me a lot of time over having to open a program :).
I’m a TED video junkie. I always have videos on my PSP ready to watch. I also like to put YouTube videos on there. I did this enough that I created a script for it that makes putting videos on my PSP real easy:
pspvidconv <d*> <video(s)> - Convert videos to PSP (d to use directory)
The PSP allows use of a single-depth directory. The directory option (when using
d flag) will ask if the user wants to create a new directory, if the answer is no, it will present the existing ones.
Because I’ve found that options and settings change frequently with encoding tools, it is better to have an expert be able to handle them (otherwise, I will spend more time looking options up again). A good program to use is h264enc. It’s a shell script (perl, I believe) and well done; not good for many files as all settings will have to be re-entered but does a good job.
For Handbrake GUI I found this post. I have yet to find any
handbrake-cli lines that work.
When I discovered MarkDown I was in love, it was very nice to discover an easy, clean, well-thought-out markup language. I wanted a way to be able take my detailed notes, have them easy to read, and then to be able post them here on the blog that would be in a nice WordPress format. Yesterday, I wrote about discovering
pandoc which enables a person to write in markdown and have it converted to HTML. To be able to use the HTML code created by
pandoc in WordPress it needed to be slightly edited and cleaned up. Therefore,… I created a bash script for it.
It works pretty good. Basically it removes tags for paragraphs (
<p>), cleans up code blocks, improves formating, as well as doing a few other things. I haven’t gone through all permutations that pandoc conversion can do so a few thing swill be left out, but otherwise it should work for most things. If anything needs to be added please let me know.
I wanted a way to easily download source files for quick editing. Sure
abs and numerous AUR-helpers do it but I wanted a simple all-together program/script that could do it, and it turned out to be pretty easy. I wanted to be able to define the repository, and then the package and I did it!
aur/ can be used here as well as the other repositories. I set up
$XDG_CONFIG_HOME/cower/config to use my pkgbuilds directory
TargetDir = /home/todd/.arch/pkgbuild/aur respectively) so it looks pretty nice:
ls aur extra own testing
If the repository is wrong it will list the available repositories:
pacpull extar/a52dec Not a valid repository: core extra community multilib testing community-testing multilib-testing
And it’s nice and it’s basic: