git bisect start # Search start git bisect bad # Set point to bad commit git bisect good v2.6.13-rc2 # Set point to good commit|tag git bisect bad # Say current state is bad git bisect good # Say current state is good git bisect reset # Finish search
Find lines matching the pattern (regex or string) in tracked files
1
git grep --heading --line-number 'foo bar'
Forced push but still ensure you don’t overwrite other’s work
# ${VAR^} # upper single # ${VAR^^} # upper all # ${VAR,} # lower single # ${VAR,,} # lower all # ${VAR~} # swap case single # ${VAR~~} # swap case all
VAR=BAR printf${VAR,,}# bar
same thing with string replacement.
1 2 3 4 5 6 7 8
# ${VAR/PATTERN/STRING} # single replacement # ${VAR//PATTERN/STRING} # all match replacement # Use ${VAR#PATTERN} ${VAR%PATTERN} ${VAR/PATTERN} for string removal
VAR=foofoobar ${VAR/foo/bar}# barfoobar ${VAR//foo/bar}# barbarbar ${VAR//foo}# bar
Avoid seq for ranges
Use the built in {x..y} expression instead.
1 2 3
for k in {1..100}; do $(do_awesome_stuff_with_input ${k}) done
disown is a bash built-in that can be used to remove a job from the job table of a bash script. You can remove one or multiple of these processes with disown and the script will not care about it anymore.
Basic parallelism
Usually people use & to send a process to the background and wait to wait for the process to finish.
People then often use named pipes, files and global variables to communicate between the parent and sub programs.
xargs
For file-based in-node parallelization, xargs is the easiest way to parallelize the processing of list elements.
1 2 3 4 5 6 7 8 9
# simple example: replace all occurences of "foo" with "bar" in ".txt" files # will process each file individually and up 16 processes in parallel find . -name "*.txt" | xargs -n1 -P16 -I{} sed -i 's/foo/bar/g' {}
# complex example: HDF5 repack for transparent compression of files # find all ".h5" files in "${dirName}" and use up to 64 processes in parallel to independently compress them find ${dirName} -name "*.h5" | xargs -n1 -P64 -I{} \ sh -c 'echo "compress $1 ..." && \ h5repack -i $1 -o $1.gz -f GZIP=1 && mv $1.gz $1' _ {}
do_stuff ${withinput} || fail "did not do stuff correctly"${FILENAME}${LINENO} $?
Trapping on EXIT instead of a specific signal is particularly useful for cleanup handlers since this executes the handler regardless of the reason for the script’s termination. This also includes reaching the end of your script and aborts due to set -e.
You don’t need cat
Sometimes cat is not available, but with bash you can read files anyhow.
log=""# numeric, log table=""# single fill stores=( ) # array
# : after a letter is for string into parameter whilegetopts":dhls:t:" opt; do case"${opt}"in d) set -x ;; h) printf"Help page\n" ; exit ;; s) stores[${#stores[*]}]="${OPTARG}" ;; t) if [ -z "${table}" ]; then table="${OPTARG}" fi ;; l) (( log++ )) ;; *) printf"\n Option does not exist: %s\nOne option\n"${OPTARG} exit 1 ;; esac done
# set debug if log is more than two [[ "${log}" >= 2 ]] && { set -x ; log="" } [[ "${log}" == "" ]] && unsetlog
Use the #!/usr/bin/env bash shebang wherever possible.
Memorize and utilize set -eu -o pipefail at the very beginning of your code.
Never write a script without set -e at the very very beginning.
This instructs bash to terminate in case a command or chain of command finishes with a non-zero exit status, avoiding unhandled error conditions.
Use constructs like if myprogramm --parameter ; then ... for calls that might fail and require specific error handling. Use a cleanup trap for everything else.
Use set -u in your scripts.
This will terminate your scripts in case an uninitialized variable is accessed.
Uninitialized variables will fail in case it’s used in another script which sets the -u flag, better for security.
Use set -o pipefail to get an exit status from a pipeline (last non-zero will be returned).
Never use TAB for indentation.
Consistently use two (2) or four (4) character indentation.
Always put parameters in double-quotes: util "--argument" "${variable}".
Avoid putting if .. then, while .. do, for .. do, case .. in on a new line.
1 2 3 4 5 6 7 8 9 10 11
if${event}; then ... fi
while${event}; do ... done
for v in${list[@]}; do ... done
Never forget that you cannot put a space/blank between a variable name and it’s value during an assignment
1 2
RET1=false# assign RET2 = false# will not assign
Always set local function variables local.
Write clear code.
Never obfuscate what the script is trying to do.
Never shorten uncessesarily with a lot of commands per line of code chained with a semicolon.
Bash does not have a concept of public and private functions.
Public functions get generic names, whereas.
Private functions are prepended by two underscores (RedHatconvention).
#!/usr/bin/env bash # # AUTHORS, LICENSE and DOCUMENTATION # set -eu -o pipefail
Readonly Variables Global Variables
Import ("source scriptname") of external source code
Functions `-. functionlocal variables `-. clearly describe interfaces: return either a code or string
Main `-. option parsing `-. log file and syslog handling `-. temp. file and named pipe handling `-. signal traps
------------------------------------------------------------------------ To keep in mind: - quoting of all variables passed when executing sub-shells or cli tools - testing of functions, conditionals and flow (see style guide) - makes restricted mode ("set -r") for security sense here?
Silence is golden - like in any UNIX programm, avoid cluttering the terminal with useless output.
It retrieves data from Amazon S3 bucket and distributes it to multiple datacenter locations.
It delivers the data through a network of data centers called edge locations. The nearest edge location is routed when the user requests for data, resulting in lowest latency, low network traffic, fast access to data, etc.
Set up
AWS Console - public bucket
Sign in to AWS management console.
Upload Amazon S3 and choose every permission public.
Go to CloudFront console: Select a delivery method for your content - > Get Started. 4.Origin Domain Name -> Amazon S3 bucket created.
Next, dafult, and Create Distribution button.
When the Status column changes from “In Progress” to “Deployed”, select the Enable option.
Wait around 15 minutes for the domain name to be available in the Distributions list.
Cloudformation - private bucket
graph LR;
A[Bucket]
B[Cloudfront]
C[User]
A -- bucket data --> B;
B -- bucket data --> C;
C --> B;
B -- request with OAI --> A;
BucketPolicy: Type:AWS::S3::BucketPolicy Properties: Bucket:private-bucket PolicyDocument: Version:'2012-10-17' Statement: -Effect:Allow Principal: AWS:!Sub'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity' # you may get the recently created with '${CloudFrontOriginIdentity}' Action:'s3:GetObject' Resource:arn:aws:s3:::private-bucket/*