Working Environment

My working environment relies on bash and git. Here I provide some background on these tools and a walkthrough for automatic, scheduled pushes to git.

Working With Bash and Git

Useful Bash Commands

login     # prompts for username and then password to log in
man       # man (command) returns documentation a command

Directory Commands

pwd       # print working directory
cd        # changes directory to home
cd \      # changes directory to (/path)
cd ..     # moves up one folder in the directory
ls -al    # lists contencts of directory, -a includes hidden items, -l includes details

File Operations

mkdir    # make a new directory
touch    # create a file
open     # open a file
mv       # move (file) (to), can also be used to rename a file
cp       # copy (file) (to) 
rm       # delete a file

Other Utilities

echo    # print commands screen
date    # print date
cal     # print calendar (year)

Creating Custom Commands

This section is partially based on this Medium blog post.

Use the alias command to map an execution of bash commands to a single command. For example, this will create a command ‘hi’ where the Luca voice slowly says ‘hello world’;

alias hi="say -v Luca  -r 100 'hello world'"
hi # test this alias

Functions can be created with the following syntax;

function function_name() {
 <args> 
}

Inputs are denoted with $1, $2, … . For example, when called from the terminal, this function will print ‘Your Input Was:’ followed by the first argument it receives;

function print_my_input() {
 echo 'Your Input Was:' $1 
}

To create a file where custom commands are defined, navigate to the home directory, create, and open the file that will hold function definitions;

cd 
touch .custom_commands
open .custom_commands

Define commands you wish to use in future Terminal sessions in the .custom_commands file. The next section describes how to source this file automatically when a Terminal session is initialized.

Sourcing Files During Terminal Initialization

This section is partially based on this StackOverflow post

Bash sources a run control file (~/.bashrc) at initialization. Check if this file exists in the home directory with;

cd
ls -a

If there is no .bashrc file listed, then first open the .bash_profile file in a text editor and add the following;

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

Then create and open a .bashrc file in the home directory with;

cd
touch .bashrc
open .bashrc

In a text editor add the following lines to the .bashrc file;

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# source file with function definitions
source ~/.custom_commands

This last line will source the .custom_commands file described at the end of the previous section, thereby defining any aliases or functions in the .custom_commands file whenever a Terminal session is initialized.

Scheduling Bash Functions With Crontab

Some basic crontab commands;

crontab -l # lists crontab jobs
crontab -r # removes all crontab jobs
crontab -e # edits list of crontab jobs

The crontab -e command is somewhat hard to navigate, the following code is an easier way to create crontab jobs from ther terminal;

crontab -l | { cat; echo "* * * * * some entry"; } | crontab -

# format for string argument for crontab;
* * * * * "some entry"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

I simplify this farther in a custom function called ‘schedule’ that I define in .

To execute functions from a user, the user must be specified in /etc/cron.allow – however, this file can only be edited by a superuser. To create and edit this file, use;

cd /etc
sudo touch cron.allow
sudo nano cron.allow

nano opens a text editor in ther terminal, and that can be used to edit and save changes to cron.allow.

More information on crontab here.

Git and GitHub

Setup

# create user name and email for tagging contributions later
git config --global user.name "USERNAME"   
git config --global user.email "EMAIL" 

Connecting to Git can be done through a username/password or through SSH verification.

Username/Password

This didn’t work for ubdates scheduled through crontab.

SSH

First, check for SSH keys with;

cd ~/.ssh  # navigate to user/.ssh folder
ls -a      # list all files

A public SSH key is in id_rsa.pub, which can be opened in a text editor.

If no id_rsa file exists, or if you wish to create a new SSH key, you can use the following command to generate a new SSH key;

ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # run this if id_rsa file does not exist

This will prompt you for the file location where the SSH key should be saved – id_rsa is the default file.

From here, follow the steps to add an SSH key, summarized below.

First, create a config file for the SSH agent with;

touch ~/.ssh/config

Open the config file in a text editor and add the the following commands;

Host *
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rsa

Next, from Terminal, add the key from the file (e.g. id_rsa) to the ssh agent with;

ssh-add -K ~/.ssh/id_rsa

Finally, add the ssh key to the GitHub account.

And test the connection with;

ssh -T git@github.com

Working From a Repository

Create a repository through GitHub’s user interface (log in and select ‘new repository’).

Then create a directory on a local computer, possibly using bash commands; mkdir and cd.

The simplest way is to clone the repo from GitHub with;

git clone (url)     # this will clone from the url to the current directory

Another way, from inside the directory that is to be the local repo, issue these commands;

git init   # initialize a repo
git remote add origin (url or SSH address) # point local repo to remote repo

Switching between SSH and HTTPS Access

In both examples below, replace ‘USERNAME/REPOSITORY’ with the appropriate values. From within the local repo folder,

Change from HTTPS to SSH with;

git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
git remote -v # list fetch and push destinations, should start with git@github.com

Change from SSH to HTTPS with;

git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
git remote -v # list fetch and push destinations, should start with https://github.com/

More detailed guide here.

Other methods for addressing ‘Device not configured’ errors here.

Repository Maintanence And Collaboration

Git workflow

Git workflow

Useful commands;

git pull    # adds files from the configured remote repo to your local repo and workspace
git add .   # adds all new files to be tracked
git add -u  # updates all files
git add -A  # does both '.' and '-u'
git commit -m "message" # saves changes local repo
git push    # updates repo on GitHub

Collaborators can all access the GitHub repo through push/pull commands. In collaborative settings you might need to pull, so that your repository is current, before pushing changes from the local repository to the remote repository on GitHub.

Useful Custom Aliases and Functions

gitup: combines add, commit, and push into one command

alias gitup="git add -A; git commit -m 'auto'; git push"

gitupall: updates all git repos in my git folder

function gitupall{
for filename in /Users/mac/git/*; do
echo "**************************updating $filename"
cd "$filename"; 
gitup
cd ..
done
}

schedule: schedules a command to be executed periodically

function schedule(){
crontab -l | { cat; echo "$1"; } | crontab -
}

# format for string argument for crontab;
* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Example use;

# e.g. use: schedule updating of all repos each hour
schedule "0 0-23 * * * gitupall"
crontab -l # lists crontab jobs after schedule call

My Setup

Bash Aliases, Functions, Scheduled Commands

In my root directory, I have a file called .custom_commands with contents;

# aliases

# goes to my folder of git projects
alias gitgo="cd /Users/mac/git; ls"
echo 'sourced alias gitgo'

# pushes updates on a git project
alias gitup="git add -A; git commit -m 'auto'; git push"
echo 'sourced alias gitup'

# functions

# schedule "(m h DoM M DoW command)"
# schedules command to be executed at 
# minute m of hour h on DoM days of the month in months M or DoW days of the week.
function schedule(){
crontab -l | { cat; echo "$1"; } | crontab -
}
echo 'sourced function schedule'

# for updating all git projects, schedule this to be done periodically
function gitupall(){
for filename in /Users/mac/git/*; do
echo "************************** updating $filename"
cd "$filename";
git remote -v    # prints the fetch and push destinations
gitup
done
cd # return to home directory
}
echo 'sourced function gitupall'

I also have a .bashrc file in my root directory, which sources the custom commands. Particularly the contents of the .bashrc file are;

# Source system-wide definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# source file with function definitions
source ~/.custom_commands

I also have a file in my root directory for scheduling, called .scheduled with contents;

# put all scheduled functions here

# source custom commands
source ~/.custom_commands

# activate key agent
eval "$(ssh-agent -s)"

# test SSH key / print username
ssh -T git@github.com

# update all git repos
gitupall

I then scheduled this file to be read hourly by opening a terminal session, which sources .bashrc at initialization thereby sourcing my custom commands, and running;

schedule "0 0-23 * * * source ~/.scheduled"
crontab -l # the scheduled job should be listed as a crontab job