This is the last article in the series of scripts. We will take the script from Part 8 and continue with it. We will be taking our folderCreator script and using it in our distribution process.
Distribution is the process of placing the script along with any supporting resources on a destination computer making it easily available for use. There are many aspects to this process, but we are going to look at a few of them:
- Where should our script be installed?
- How will the end user be invoking the script?
- Does the script have its own man page?
Creating our own commands from other shell scripts
You may have noticed that whenever we use commands like defaults, echo, ls, cd, … we do not have to specify the path to the command. There is a reason for that. When we run our script the shell interpreter ‘knows’ where to go and look for these commands. There are some predefined locations available. We can get these predefined locations from the environment.
printenv PATH
This gives us an output that looks like:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
The output you see will vary from computer to computer. As we can see it is a list of folders separated by a ‘:’. These are the folders the interpreter will go through to locate the commands we use.
While we do not specify the path to a command in our script it is actually considered good practice. In fact, we will be making the same change to our script.
So if we want our own commands to be located easily it should be placed in one of these folders.
Installing commands
While installing commands there is one feature of macOS that we need to keep in mind: SIP (System Integrity Protection). Introduced in OS X 10.11 El Capitan, SIP prevents the modification of certain system files or folders even if you have root privileges. So this means that we do not have a lot of choice when it comes to installing our command. We will place it in /usr/local/bin
folder.
Here is the final version of the folderCreator script. I have added paths to some commands and have kept the file name as folderCreator. The version number has been removed from the file name.
#!/bin/zsh
#-------------------------------------------------------------------------------------------------
#NAME: Folder creator
#AUTHOR: Arun Patwardhan
#CONTACT: arun@amaranthine.co.in
#DATE: 15th September 2022
#WEBSITE: https://github.com/AmaranthineTech/ShellScripts
#-------------------------------------------------------------------------------------------------
#LEGAL DISCLAIMER --------------------------------------------------------------------------------
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.
#-------------------------------------------------------------------------------------------------
#LICENSE/TERMS AND CONDITIONS --------------------------------------------------------------------
#MIT License
#Copyright (c) Amaranthine 2021.
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#-------------------------------------------------------------------------------------------------
#ABOUT -------------------------------------------------------------------------------------------
# fileCreator.zsh
# 1.8
#-------------------------------------------------------------------------------------------------
#DESCRIPTION -------------------------------------------------------------------------------------
# - THis script is intended for creating the custom folders that are required on all corporate computers.
# - Run this script on a new computer or a computer being reassigned to another employee.
# - This script can run on all computers.
#-------------------------------------------------------------------------------------------------
#USAGE -------------------------------------------------------------------------------------------
# - To create folders with default names run the command: ./folderCreator.zsh
# - To define your own folder names: ./folderCreator.zsh <folder1> <folder2> <folder3>
# - Available options : Only the help option is available
# - Getting help : Use the -h or the -help options to get more information. Or you can use the man command to view the man page.
#-------------------------------------------------------------------------------------------------
#WARNING/CAUTION ---------------------------------------------------------------------------------
#******************************************************************************************************************
#******************************************************************************************************************
#******************************************************************************************************************
#******************************************************************************************************************
# This script doesn't perform any validation of the folder names being passed in by the user.
# If the script does not see the -h or the -help options then it will assume that the data being passed in is the name of the folder.
# The user of the script must ensure that the desired folder names are passed in.
#******************************************************************************************************************
#******************************************************************************************************************
#******************************************************************************************************************
#******************************************************************************************************************
#-------------------------------------------------------------------------------------------------
#INSTALLATION ------------------------------------------------------------------------------------
# Instructions for placing the script in the correct place are listed here.
# Location: /Library/Scripts/
# Permissions: rwx r-x r-x
#-------------------------------------------------------------------------------------------------
#REQUIREMENTS ------------------------------------------------------------------------------------
# Shell: /bin/zsh
# OS: macOS Big Sur 11.4 or later
# Dependencies: None
#-------------------------------------------------------------------------------------------------
#HELP/SUPPORT ------------------------------------------------------------------------------------
# You can get help by running the following commands.
# ./folderCreator.zsh -h
# ./folderCreator.zsh -help
# OR
# man folderCreator.zsh
# You can also view the log file for the same at: ~/Library/Logs/folderCreator_log_v1-8.log
#-------------------------------------------------------------------------------------------------
#HISTORY -----------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------
# Version 1.0: Basic script which creates the folders
# Version 1.1: Gives user the ability to specify the folder names at run time.
# Version 1.2: Adds safety checks to the scripts
# Version 1.3: Includes documentation as well as ability to get help.
# Version 1.4: Includes optimisation using for loop
# Version 1.5: Prompts the user in the GUI for names for the different folders.
# Version 1.6: Updated the log mechanism with the help of a function and here document.
# Version 1.7: Replaced the folder variables with an array
# Version 1.8: Added absolute path for commands. Final version ready for deployment.
#-------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------
# ------------------------------ SCRIPT STARTS HERE ----------------------------------------------
#-------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------
#These are the default values used for the folder names incase the user doesn't provide any.
FOLDERS=("Tools" "Reports" "Help")
#Script version number
VERSION_NUMBER="1.8"
#Command name
COMMAND_NAME="folderCreator.zsh"
#1. Check to see if the user is asking for help. In which case we will have to provide information about the command.
if [[ $1 == "-h" ]] || [[ $1 == "-help" ]]; then
echo "ABOUT
-----
fileCreator.zsh
Version $VERSION_NUMBER
NAME
----
$COMMAND_NAME — Folder creation utility SYNOPSIS
$COMMAND_NAME folder names [ verbs ]
DESCRIPTION
-----------
$COMMAND_NAME creates 3 folders in the home folder. In case the folder names are not provided then the command will create folders with default names 'Tools', 'Reports', \"Help\".
There is also the option of getting help via the help verb.
- This script is intended for creating the custom folders that are required on all corporate computers.
- Run this script on a new computer or a computer being reassigned to another employee.
- This script can run on all computers.
VERBS
-----
[ −h −help] Both the options are used to invoke the help documentation.
[ −v −version] Both the options are used to get the version number of the folderCreator command.
REQUIREMENTS
------------
The following are the minimum requirements to get the script running.
Shell: zsh
OS: macOS Big Sur 11.4 or later
Dependencies: None
INSTALLATION
------------
$COMMAND_NAME can be installed anywhere you wish. However, there are certain locations that are recommended.
Location: /Library/Scripts/
Permissions: rwxr-xr-x
USAGE
-----
$COMMAND_NAME folder1 folder2 folder3
Will create folders with your own names.
$COMMAND_NAME -h OR $COMMAND_NAME -help
Will invoke the help utility.
$COMMAND_NAME -v OR $COMMAND_NAME -version
will print the version number in stdout.
WARNING/CAUTION
---------------
$COMMAND_NAME does not perform any validation of names. The only options that folderCreator accepts are -h and -help verbs or the -v and
-version verbs. If the script does not see the -h , -help or the -v , -version options then it will assume that the data being passed in is
the name of the folder. The user of the folderCreator command must ensure that the desired folder names are passed in. The user will also be
prompted, via the graphical user interface, if he/she wishes to provide the names for the folders. If yes, then there will be subsequent
prompts asking for the folder names.
EXAMPLES
--------
$COMMAND_NAME Resources Results Assistant
This will create 3 folders Resources , Results , Assistant , in the user’s home folder.
$COMMAND_NAME
This will create 3 folders with the default names
$COMMAND_NAME Apps
This will use the Apps name for the first folder but the default names for the last 2 folders.
NOTE
----
The user will be asked if he/she wishes to provide custom names in all the examples mentioned above. The user's value will always override
whatever is being provided to the script or defaults.
DIAGNOSTICS
-----------
The script produces a log file called ~/Library/Logs/folderCreator_log_v1-x.log
This file is typically located in the user’s home folder log folder. The x represents the version number of $COMMAND_NAME
You can view the logs for each respective version.
COPYRIGHT
---------
Copyright (c) Amaranthine 2015-2021. All rights reserved. https://amaranthine.in
EXIT STATUS
-----------
In most situations, $COMMAND_NAME exits 0 on success"
exit 0
fi
PATH_TO_LOG="$HOME/Library/Logs/folderCreator_log_v1-8.log"
# Function to log activity
function recordActivity() {
/bin/cat << EOF >> $PATH_TO_LOG
[$(date)] $1
EOF
}
echo "$(date) Running script $0 to create folders."
echo ""
TODAY=$(date)
recordActivity "Starting"
#2. Check to see if the version number is
if [[ $1 == "-version" ]] || [[ $1 == "-v" ]]; then
echo "Version: $VERSION_NUMBER"
exit 0
fi
#3. The following if statements check to see if the script is receiving any arguments. It then picks those arguments and assigns them to the respective variables for use in the script.
if [[ $1 != "" ]]; then
FOLDERS[0]=$1
fi
if [[ $2 != "" ]]; then
FOLDERS[1]=$2
fi
if [[ $3 != "" ]]; then
FOLDERS[2]=$3
fi
#4. We can prompt the user to see if they wish to provide folder names themselves. This will override any values provided as arguments.
userClicked=$(/usr/bin/osascript -e 'button returned of (display dialog "Would you like to provide names for the folders or use the defaults instead?" buttons {"Custom", "Default"} default button 2 with icon POSIX file "/System/Library/CoreServices/HelpViewer.app/Contents/Resources/AppIcon.icns")')
# if the user decides to provide custom names then go ahead and ask the user via GUI prompts. Otherwise use the values sent as arguments or defaults.
if [[ $userClicked == "Custom" ]]; then
recordActivity "The user decided to provide custom names."
FOLDERS[0]=$(/usr/bin/osascript -e 'text returned of (display dialog "Enter the name of folder 1" default answer "Utilities" buttons {"OK"} default button 1 with title "Folder that will hold the utilities" with icon POSIX file "/Users/Shared/Finder.icns")')
FOLDERS[1]=$(/usr/bin/osascript -e 'text returned of (display dialog "Enter the name of folder 2" default answer "Tools" buttons {"OK"} default button 1 with title "Folder that will hold the tools" with icon POSIX file "/Users/Shared/Finder.icns")')
FOLDERS[2]=$(/usr/bin/osascript -e 'text returned of (display dialog "Enter the name of folder 3" default answer "Help" buttons {"OK"} default button 1 with title "Folder that will hold the support documents" with icon POSIX file "/Users/Shared/Finder.icns")')
recordActivity "User provided: ${FOLDER[@]}"
else
recordActivity "User decided to use default values: ${FOLDER[@]}"
fi
#5. Go to the home folder.
cd $HOME
#6. Check to see if each of the folders exists. If it exists then do not create it. Else create the folder.
recordActivity "Creating folders: ${FOLDER[@]}"
for item in ${FOLDER[@]}; do
if [[ -d $item ]]; then
recordActivity "Not creating $item as it already exists."
else
recordActivity "Creating $item"
/bin/mkdir $item
fi
#7. Create the task completion file inside each folder.
recordActivity "Creating hidden file for $item folder."
cd $item
#8. Generate the file names based on the folder names.
/usr/bin/touch ".$item-FolderCreated"
cd ..
done
echo "$(date) Task completed. Have a nice day!"
#-------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------
# ------------------------------ END OF SCRIPT ---------------------------------------------------
In order to run this command we will have to give it execute capabilities.
chmod 755 folderCreator
This should change the icon of the script to that of an executable. If it doesn’t then go ahead and remove the extension from the file.
Copy the file to the /usr/local/bin
folder. You will need to authenticate as admin to do this. There may be other executables in this folder.
Using commands
Now let us test to see if this has worked. Run the command:
folderCreator -h
We can use the which
command to confirm that the correct binary is being used.
which folderCreator
Adding path to the environment
Now, it is not necessary that the executables we create should be placed in one of the standard PATH folders. We could place it anywhere else. All we would have to do is to export this new folder path to the PATH environment variable. There are a few ways of doing this.
- Use the export command
- Source another script file into your script
- Automatically configure bash/zsh to source the export command
Using the export command
The export command temporarily adds a value to the PATH environment variable. We could do this at the start of the script. Let us look at this as an example.
- Create a script, message.bash and save it in the /Users/Shared/Scripts/.
#!/bin/bash
echo "$(date) This is a random script $RANDOM"
- Create another script called test.bash and save it where ever you want.
#!/bin/bash
export DEVELOPER_PATH=/Users/Shared/Scripts/
export PATH=$DEVELOPER_PATH:$PATH
bash welcome.bash
which welcome.bash
- Run the script with the command: bash test.bash. Don’t forget to put the path when using the script.
The 2 export commands are setting the value of the PATH environment variable to the new path. Note that while doing that we still keep the existing PATH value. So the environment will contain all the existing PATHS as well as the new path.
We can immediately see the benefit of adding another folder to our PATH component. The commands on line 6 and 8 do not require the path to the welcome.bash script to be explicitly mentioned. Even though they are not in the standard search paths. In fact, any script/executable that is placed in that folder will now be directly accessible without having to specify the absolute path. Having said that it is still a good idea to put the absolute path to a command.
An important thing to keep in mind is that this change only applies to the script that we are running. This will not impact other shells or other scripts running in the same shell. The next 2 options will show us how we could possibly do that.
Source the export commands from another script
If the export commands are needed in more than one script then it might be a good idea to source them instead of rewriting them over and over again.
Start off by creating a new file called newPath.bash. It should only have the 2 export commands in them.
#!/bin/bash
export DEVELOPER_PATH=/Users/Shared/Scripts/
export PATH=$DEVELOPER_PATH:$PATH
Now we will modify our test.bash script from the previous example as shown below.
#!/bin/bash
#Using source
source /Users/Shared/newPath.bash
bash welcome.bash
which welcome.bash
You can see that we simply source the original script in here. This is extremely useful if there are multiple paths that need to be added to multiple scripts. Any change in the path only has to be made in one place making this approach far more convenient and scalable. There is still the same catch. Any change to the path is only applicable to the scope of the script. Other scripts and the shell environment itself does not get affected.
Configure bash/zsh to source our export commands.
While the pervious 2 approaches are good, they have the limitation that the changes are only applicable to the script where the sourcing is done. All the other scripts and the shell itself are not affected by it. Now this maybe a desired outcome. There are situations where you would want this to be applicable globally to all the scripts and the shell itself without having to change the PATH value manually by ourselves. This can be done by changing the scripts that are invoked when the shell is loaded.
The file that is to be invoked is located in the /etc folder. It is called zshrc. If you want to make a change to bash shell then you need to modify bashrc. Copy this file to your desktop. Change it as shown below.
# System-wide profile for interactive zsh(1) shells.
# Setup user specific overrides for this in ~/.zshrc. See zshbuiltins(1)
# and zshoptions(1) for more details.
# Correctly display UTF-8 with combining characters.
if [[ "$(locale LC_CTYPE)" == "UTF-8" ]]; then
setopt COMBINING_CHARS
fi
# Disable the log builtin, so we don't conflict with /usr/bin/log
disable log
# Save command history
HISTFILE=${ZDOTDIR:-$HOME}/.zsh_history
HISTSIZE=2000
SAVEHIST=1000
# Beep on error
setopt BEEP
# Use keycodes (generated via zkbd) if present, otherwise fallback on
# values from terminfo
if [[ -r ${ZDOTDIR:-$HOME}/.zkbd/${TERM}-${VENDOR} ]] ; then
source ${ZDOTDIR:-$HOME}/.zkbd/${TERM}-${VENDOR}
else
typeset -g -A key
[[ -n "$terminfo[kf1]" ]] && key[F1]=$terminfo[kf1]
[[ -n "$terminfo[kf2]" ]] && key[F2]=$terminfo[kf2]
[[ -n "$terminfo[kf3]" ]] && key[F3]=$terminfo[kf3]
[[ -n "$terminfo[kf4]" ]] && key[F4]=$terminfo[kf4]
[[ -n "$terminfo[kf5]" ]] && key[F5]=$terminfo[kf5]
[[ -n "$terminfo[kf6]" ]] && key[F6]=$terminfo[kf6]
[[ -n "$terminfo[kf7]" ]] && key[F7]=$terminfo[kf7]
[[ -n "$terminfo[kf8]" ]] && key[F8]=$terminfo[kf8]
[[ -n "$terminfo[kf9]" ]] && key[F9]=$terminfo[kf9]
[[ -n "$terminfo[kf10]" ]] && key[F10]=$terminfo[kf10]
[[ -n "$terminfo[kf11]" ]] && key[F11]=$terminfo[kf11]
[[ -n "$terminfo[kf12]" ]] && key[F12]=$terminfo[kf12]
[[ -n "$terminfo[kf13]" ]] && key[F13]=$terminfo[kf13]
[[ -n "$terminfo[kf14]" ]] && key[F14]=$terminfo[kf14]
[[ -n "$terminfo[kf15]" ]] && key[F15]=$terminfo[kf15]
[[ -n "$terminfo[kf16]" ]] && key[F16]=$terminfo[kf16]
[[ -n "$terminfo[kf17]" ]] && key[F17]=$terminfo[kf17]
[[ -n "$terminfo[kf18]" ]] && key[F18]=$terminfo[kf18]
[[ -n "$terminfo[kf19]" ]] && key[F19]=$terminfo[kf19]
[[ -n "$terminfo[kf20]" ]] && key[F20]=$terminfo[kf20]
[[ -n "$terminfo[kbs]" ]] && key[Backspace]=$terminfo[kbs]
[[ -n "$terminfo[kich1]" ]] && key[Insert]=$terminfo[kich1]
[[ -n "$terminfo[kdch1]" ]] && key[Delete]=$terminfo[kdch1]
[[ -n "$terminfo[khome]" ]] && key[Home]=$terminfo[khome]
[[ -n "$terminfo[kend]" ]] && key[End]=$terminfo[kend]
[[ -n "$terminfo[kpp]" ]] && key[PageUp]=$terminfo[kpp]
[[ -n "$terminfo[knp]" ]] && key[PageDown]=$terminfo[knp]
[[ -n "$terminfo[kcuu1]" ]] && key[Up]=$terminfo[kcuu1]
[[ -n "$terminfo[kcub1]" ]] && key[Left]=$terminfo[kcub1]
[[ -n "$terminfo[kcud1]" ]] && key[Down]=$terminfo[kcud1]
[[ -n "$terminfo[kcuf1]" ]] && key[Right]=$terminfo[kcuf1]
fi
# Default key bindings
[[ -n ${key[Delete]} ]] && bindkey "${key[Delete]}" delete-char
[[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line
[[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line
[[ -n ${key[Up]} ]] && bindkey "${key[Up]}" up-line-or-search
[[ -n ${key[Down]} ]] && bindkey "${key[Down]}" down-line-or-search
# Default prompt
PS1="%n@%m %1~ %# "
# Useful support for interacting with Terminal.app or other terminal programs
[ -r "/etc/zshrc_$TERM_PROGRAM" ] && . "/etc/zshrc_$TERM_PROGRAM"
if [[ -f /Users/Shared/newPath.bash ]]; then
source /Users/Shared/newPath.bash
fi
Save this file back to the etc folder. It might be a good idea to take a backup of the original file in case we need to restore it back to undo any errors we might introduce.
Open the terminal app. Run the welcome.bash script without providing the path. See if it works.
Run the command to print the path variable:
printenv PATH
As we can see, there is no need to run the export command repeatedly. There is no need to source the file that contains those commands either.
Standard location or custom path
This approach does give us a lot of flexibility. However, we can see that there are several things we need to do before we can get everything working well. It might be better for us to place our commands in the standard /usr/local
folder. That would make the deployment a lot easier.
Man pages
What are man pages?
If you have used the command line interface on macOS/Unix/Linux then you would be familiar with the man
command. In case you aren’t then the man command is the command that loads the manual for the binary specified. It is a quick easy way to access the documentation and help for the command. However, man pages aren’t restricted to only binaries. They could be applied on normal files too.
There is one thing to keep in mind. It is not necessary that a man page exists for a given command. Try running the command man folderCreator
. What do you get?
No manual entry for folderCreator
We get a message saying that there is no manual entry for our binary. So we need to go ahead and create one.
Before I talk about how to create them I will first address the question of whether we need to create one in the first place. Especially since we are already providing help view the -h -help options. Actually we don’t have to. However, keep in mind that most users are already familiar with the man command and their instinctive reaction is to look for the man page of your command. It would be very nice to offer them that ability.
How do we create them?
In order to create our man page we need to use certain macros that render the document for us. More information can be available via the mandoc
, groff
, mdoc
, and man
commands. I would highly recommend going through the man pages of these commands.
man pages are simple files that contain information which is formatted with the help of different macros. A typical man page contains the following sections in the specified sequence:
- NAME
- SYNOPSIS
- DESCRIPTION
- VERBS
- REQUIREMENTS
- INSTALLATION
- USAGE
- WARNINGS
- EXIT STATUS
- EXAMPLES
- DIAGNOSTICS
- COPYRIGHT
- CONTACT DETAILS
There are other sections available too: the man page for groff
command contains excellent information about that. Armed with the information about which sections are there within the man page we need to start gathering all our details together.
One piece that we need is the manual section.If we run the man command on man:
man man
It gives us some information about the manual sections. The sections describe the kinds of commands and potentially the actions they perform. Our command would fall under the user commands section or section 1.
Where are they located?
These files are located in the /usr/local/share/man/man1
folder. Where man1 represents the section number.
Let us try to create the file. Before that we will look at some macros that we would need.
Macro | Description |
---|---|
.Dd | This is used to specify the date when the man page was created/published. |
.Dt | This is used to specify the title for the man page. Its value should always be in all caps. |
.Os | The name of the operating system. |
.Sh | Section header name, |
.Nm | The name of the command. This is the name that will be used throughout the document. |
.Nd | The description of the command. |
.Ar | Arguments being passed to a command |
.Op | Options being passed to a command |
.Pp | New paragraph |
.Bl | Start a list |
.El | End the list |
.Ev | For environment variables |
.It | Italics |
.Ss | Subsection |
.An | Name of the author |
.Sy | Symbolic font mode |
.\" | Comment |
You can get more details and information about these macros by running the following command:
man mdoc
We will now use these macros to render our man page. The easiest way to do this would be to use an existing man page file as a template. The idea is to use the macros to do the rendering for us. Copy paste the contents of any existing man page into your file and start replacing the content with your own content. You can always test your page by using the man command directly on your file.
man /path/to/your/manpage/file.1
A good thing to do would be to add 1 item at a time and run the above command repeatedly till you get comfortable with how everything fits together.
If you need help correcting the formatting of the file run the following command:
mandoc -T lint folderCreator.1
This is how the man page file looks. Name it folderCreator.1 where the ‘1’ indicates the section number.
.\"Copyright (c) 2015-2022 Amaranthine. All Rights Reserved. | |
.\" | |
.\" | |
.Dd August 10, 2021 | |
.Dt FOLDERCREATOR 1 | |
.Os macOS 11 | |
.Sh NAME | |
.Nm folderCreator | |
.Nd Folder creation utility | |
.\" | |
.\" ============================================================================ | |
.\" ========================== BEGIN SYNOPSIS SECTION ========================== | |
.Sh SYNOPSIS | |
.Nm | |
.Ar "folder names" | |
.Op verbs | |
.\" =========================== END SYNOPSIS SECTION =========================== | |
.\" ============================================================================ | |
.\" | |
.\" ============================================================================ | |
.\" ======================== BEGIN DESCRIPTION SECTION ========================= | |
.Sh DESCRIPTION | |
.Nm | |
creates 3 folders in the home folder. | |
In case the folder names are not provided then the command | |
will create folders with default names "Tools", "Reports", "Help". | |
.Pp | |
The user is also prompted via the graphical user interface for names that should be used for the folders. | |
This is optional and the user can cancel it. | |
.Pp | |
There is also the option of getting help via the help verb. | |
.Pp | |
- This script is intended for creating the custom folders that are required on all corporate computers. | |
.Pp | |
- Run this script on a new computer or a computer being reassigned to another employee. | |
.Pp | |
- This script can run on all computers. | |
.\" ---------------------------------------------------------------------------- | |
.\" ------------------------- BEGIN TERMINOLOGY LIST --------------------------- | |
.Sh VERBS | |
.Bl -hang | |
.It Op Fl h help | |
Both the options are used to invoke the help documentation. | |
.It Op Fl v version | |
Both the options are used to get the version number of the | |
.Nm | |
command. | |
.El | |
.\" --------------------------- END TERMINOLOGY LIST --------------------------- | |
.\" ---------------------------------------------------------------------------- | |
.\" ============================================================================ | |
.\" ======================== BEGIN REQUIREMENTS SECTION ======================== | |
.Sh REQUIREMENTS | |
The following are the minimum requirements to get the script running. | |
.Bl -hang -offset 4n -width "xxxxxxxxxxxx" -compact | |
.It Shell: | |
zsh | |
.It OS: | |
macOS Big Sur 11.4 or later | |
.It Dependencies: | |
None | |
.El | |
.Ev HOME | |
.\" ============================================================================ | |
.\" ======================== BEGIN INSTALLATION SECTION ======================== | |
.Sh INSTALLATION | |
.Nm | |
can be installed anywhere you wish. | |
However, there are certain locations that are recommended. | |
.Bl -hang -offset 4n -width "xxxxxxxxxxxx" -compact | |
.It Location: | |
/Library/Scripts/ | |
.It Permissions: | |
rwx r-x r-x | |
.El | |
.\" ============================================================================ | |
.\" ======================== BEGIN USAGE SECTION ======================== | |
.Sh USAGE | |
.Nm | |
.Ar folder1 | |
.Ar folder2 | |
.Ar folder3 | |
.Pp | |
Will create folders with your own names. | |
.Pp | |
.Nm | |
.Ar -h | |
OR | |
.Nm | |
.Ar -help | |
.Pp | |
Will invoke the help utility. | |
.Pp | |
.Nm | |
.Ar -v | |
OR | |
.Nm | |
.Ar -version | |
.Pp | |
Will print the version number in stdout. | |
.Ss GUI Interaction | |
In all cases the user is always prompted for entering folder names via the graphical user interface. | |
Therefore this script triggers a gui popup. | |
In case this is not the desired behavior then the appropriate lines of code will need to be commented out. | |
.\" ============================================================================ | |
.\" ======================== BEGIN WARNING/CAUTION SECTION ======================== | |
.Sh WARNING/CAUTION | |
.Nm | |
does not perform any validation of names. | |
The only options that | |
.Nm | |
accepts are | |
.Ar -h | |
and | |
.Ar -help | |
verbs or the | |
.Ar -v | |
and | |
.Ar -version | |
verbs. | |
If the script does not see the | |
.Ar -h | |
, | |
.Ar -help | |
or the | |
.Ar -v | |
, | |
.Ar -version | |
options then it will assume that the data being passed in is the name of the folder. | |
The user of the | |
.Nm | |
command must ensure that the desired folder names are passed in. | |
The user will also be prompted, via the graphical user interface, if he/she wishes to provide the names for the folders. | |
If yes, then there will be subsequent | |
prompts asking for the folder names. | |
.\" ============================================================================ | |
.\" ======================== BEGIN EXIT STATUS SECTION ========================= | |
.Sh EXIT STATUS | |
In most situations, | |
.Nm | |
exits 0 on success | |
.\" ============================================================================ | |
.\" ======================== BEGIN EXAMPLES SECTION ======================== | |
.Sh EXAMPLES | |
.Nm | |
.Ar Resources | |
.Ar Results | |
.Ar Assistant | |
.Pp | |
This will create 3 folders | |
.Sy Resources | |
, | |
.Sy Results | |
, | |
.Sy Assistant | |
, | |
in the user's home folder. | |
.Pp | |
.Nm | |
.Pp | |
This will create 3 folders with the default names | |
.Pp | |
.Nm | |
.Ar Apps | |
.Pp | |
This will use the | |
.Sy Apps | |
name for the first folder but the default names for the last 2 folders. | |
.\" ============================================================================ | |
.\" ======================== BEGIN DIAGNOSTICS SECTION ======================== | |
.Sh DIAGNOSTICS | |
The script produces a log file called | |
.Sy ~/Library/Logs/folderCreator_log_v1-x.log | |
.Pp | |
This file is typically located in the user's home folder log folder. | |
The x represents the version number of | |
.Nm | |
.Pp | |
You can view the logs for each respective version. | |
.\" ============================================================================ | |
.\" ======================== BEGIN COPYRIGHT SECTION ======================== | |
.Sh COPYRIGHT | |
Copyright (c) Amaranthine 2015-2021. | |
All rights reserved. | |
https://amaranthine.in | |
.\" ============================================================================ | |
.\" ======================== BEGIN CONTACT SECTION ======================== | |
.Sh CONTACT DETAILS | |
.An Author: Arun Patwardhan | |
.Pp | |
Website: https://amaranthine.in | |
.Pp | |
Email: arun@amaranthine.co.in |
Place the man page in the following folder.
/usr/local/share/man/man1/folderCreator.1
This is how it would look if we run the man command on our folderCreator script.
This is how it would look like if we opened it in the Preview application.
Video
Download
You can download the final script from here.
You can download the man page file from here.
Summary
Our script has evolved quite a bit from the first blog. We started off with a very simple script and have ended with a larger script. It still does the same thing it did originally but is now a lot better. Here are some of the key points:
- Writing event updates to log files
- User interaction
- Flexibility in terms of folder names via user interaction from the GUI as well as the command line arguments
- Easy to maintain thanks to functions
- Arrays make it scalable
- Loops help make the script compact
- Variables enhance scalability
- Periodic checks ensure the script is safe and stable
- User can get help using
- the -h or the -help options
- From the comments in the script
- by viewing the man page for the script
Of course, there is room for improvement. Some of you might come up with ways of achieving this solution differently. Which is perfectly fine. There is no such thing as a universally perfect script. The point behind the script above was to illustrate how the different features could work together.
Final thoughts
Scripting is a continuous learning process. There are so many things in it. Over time you will find that you are faced with similar challenges. One thing that a lot of script writers and programmers do is to refer to perviously written scripts to get a head start. Every time you write a script it would be a good idea to archive it and keep a copy elsewhere. This will come in handy.
Happy scripting!