-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefine_funcs
executable file
·712 lines (667 loc) · 20.4 KB
/
define_funcs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
#!/bin/bash
# define_funcs
# remember to source this BEFORE you try to export the stuff
# Complex `s3cmd` wrapper:
function s3cmd {
# define keys if needed:
if [ -z "$AWS_SECRET_KEY" ]; then
both=`gpg -o- ~/.aws/keys.gpg 2>/dev/null`
export AWS_ACCESS_KEY=`echo "$both" | awk "NR==1"`
export AWS_SECRET_KEY=`echo "$both" | awk "NR==2"`
fi
options=$"--access_key=$AWS_ACCESS_KEY --secret_key=$AWS_SECRET_KEY --config=~/.s3cfg"
if (( $# == 2 )) && [ "$1" = "du" ]; then
options="$options du $2"
echo "$options" > options.tmp
output=`command s3cmd $options 2>/dev/null`
echo "$output" | cut -d ' ' -f 1 | sed -e 's/^/scale=2; /' -e 's/$/\/1024^2/' | bc | sed 's/$/ MB/'
else
options="$options ""$@"
command s3cmd $options
fi
}
function koyae_find_home {
if [ -d "$HOME" ] || [ -L "$HOME" ]; then
printf '%s' "$HOME"
elif [ -d "~" ] || [ -L "~" ]; then
printf '%' "~"
fi
}
function karate_chop {
ustring=$(cat<<-EOF
karate_chop: utility for splitting audio and video files using ffmpeg.
Usage: karate_chop <chop_guide> <main_file> [<output_prefix> [<duration>]]
chop_guide -- absolute start-second as integer, hh:mm:ss, or file
with format:
[<file_desc>]_<start>_for_<duration>.<fileext>
where <start> and <duration> are given in
seconds
main_file -- original file from which clip will be created
output_prefix -- Prefix-string for output file. Optional.
Default: karate_chop
duration -- start-second either as seconds or as hh:mm:ss
Default: 5210 (90 minutes + 10 seconds)
EOF
)
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
1>&2 printf "%s\\n" "$ustring"
exit 1
fi
explicit_duration=0
if [ -f "$1" ]; then
1>&2 printf "Using chop-guide filename: %s\\n" "$1"
duration=$(printf "%s" "$1" | grep -oP '[0-9]+(?=\.[a-z0-9]*)$')
if [ "$duration" = ""]; then
1>&2 printf "Duration component not found in filename %s" "$1"
exit 1
fi
startsec=$(printf "%s" "$1" | grep -oP '[0-9]+(?=_for_[0-9]+\.[a-z0-9]*)$')
if [ "$startsec" = ""]; then
1>&2 printf "Start-second component not found in filename %s" "$1"
1>&2 printf "%s\\n" "$ustring"
exit 1
fi
1>&2 printf "Start-second: %s" "$startsec"
elif printf "%s" "$1" | grep -q '[0-9]\+'; then
# else if user explicitly just gave an integer start-second
startsec="$1"
integer_startsec="$1"
elif printf "%s" "$1" | grep -q '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]'; then
startsec="$1"
hour=$( echo "$1" | cut -d: -f1 )
min=$( echo "$1" | cut -d: -f2 )
sec=$( echo "$1" | cut -d: -f3 )
integer_startsec=$(($hour*3600 + $min*60 + $sec))
else
1>&2 printf "Can't make heads or tails of chop-guide %s" "$1"
1>&2 printf "%s\\n" "$ustring"
exit 1
fi
if [ $# -lt 3 ]; then
1>&2 printf "Duration: %s" "$duration"
fi
if [ -f "$2" ]; then
main_file="$2"
1>&2 printf "Main (source) file: %s" "$main_file"
else
1>&2 printf "%s is not a valid path or does not point to a regular file." "$2"
exit 1
fi
if [ $# -gt 2 ]; then
if printf "%s" "$3" | grep -q '[0-9]\+'; then
duration="$3"
1>&2 printf "Duration %s" "$duration"
else
1>&2 printf "%s not understood as a duration" "$3"
exit 1
fi
fi
ffmpeg -i "$main_file" -c:a copy -ss $startsec karate_chop_
}
function compare_text {
if [[ $# -ne 2 ]]; then
1>&2 echo "Function needs exactly 2 arguments."
exit 1
fi
# escape any spaces in second path:
two="$(printf '%s' "$2" | awk '{gsub(/ /,"\\ "); print}')"
vim "$1" -c "vs $two" -c "windo diffthis"
}
# ssh_config - set target IP-address for a host in ~/.ssh/config and in
# ~/.pg_service
function ssh_config {
if [ $# -ne 2 ]; then
echo "usage: ssh_config <server_name> <ip_address>"
return 1
fi
vim ~/.ssh/config \
-c "/\VHost $1" -c 'call system("echo " . line(".") . " > ~/ssh_config_start")' \
-c /HostName -c "normal wc$""$2" \
-c 'call system("echo " . line(".") . " > ~/ssh_config_stop")' -c wq
vim ~/.pg_service.conf \
-c "/\V[$1]" -c 'call system("echo " . line(".") . " > ~/pg_service_start")' \
-c /host -c "normal f=wc$""$2" \
-c 'call system("echo " . line(".") . " > ~/pg_service_stop")' -c wq
echo "------------------------------------"
echo "---------- ~/.ssh/config: ----------"
echo "------------------------------------"
echo "..."
echo ""
cat ~/.ssh/config | awk "NR>=$(cat ~/ssh_config_start)&&NR<=$(cat ~/ssh_config_stop)"
echo "..."
echo ""
echo "------------------------------------"
echo ""
echo "------------------------------------"
echo "------- ~/.pg_service.conf: --------"
echo "------------------------------------"
echo "..."
echo ""
cat ~/.pg_service.conf | awk "NR>=$(cat ~/pg_service_start)&&NR<=$(cat ~/pg_service_stop)"
echo "..."
echo ""
echo "------------------------------------"
cd ~
rm ssh_config_start ssh_config_stop pg_service_start pg_service_stop
cd - 1>/dev/null
}
# set_aws_credentials [<aws_credentials_file_path>[.gpg]]
# If path is omitted, function looks for ~/.aws_credentials_path for default
# Otherwise it asks interactively
function set_aws_credentials {
location="$1"
home="$(koyae_find_home)"
gpg_cmd="$(if which gpg2 >/dev/null; then echo "gpg2"; else echo "gpg"; fi)"
default_storage_path="$home/.aws_credentials_path"
if [ "$location" = "" ] && [ "$home" != "" ]; then
location="$(cat "$default_storage_path")"
fi
if [ "$location" = "" ]; then
echo "Please enter location of credentials file."
read
location="$REPLY"
else
1>&2 printf 'Using location "%s"\n' "$location"
1>&2 printf '(Provide an argument to use a different path.)\n'
fi
if [ -e "$location" ]; then
printf '%s' "$location" > "$default_storage_path"
else
1>&2 printf 'Bad locaton "%s"\n' "$locaton"
return 1
fi
credentials="$($gpg_cmd -o- "$location" 2>/dev/null)"
succ=$?
if [ $succ -eq 0 ]; then
1>&2 echo "Success."
else
1>&2 echo "Failed. Bad password?"
fi
export AWS_ACCESS_KEY_ID=$(printf "%s" "$credentials" | head -n 1)
export AWS_SECRET_ACCESS_KEY=$(printf "%s" "$credentials" | awk 'NR==2')
return $succ
}
function set_pg_credentials {
echo "Please enter your PostgreSQL password."
read -s
export PGPASSWORD="$REPLY"
1>&2 echo "Password set."
}
function set_graph_credentials {
location="$1"
if [ "$location" = "" ]; then
location="$(koyae_find_home)"
location="$location/.ms_graph_credentials.gpg"
fi
credentials="$(gpg2 -d -o- "$location")"
if [ $? -ne 0 ]; then
1>&2 echo "Failure!!"
return 1
fi
export MS_GRAPH_BEARER_TOKEN="$credentials"
1>&2 echo "Success."
}
# recursively rename (just renames files in place)
function renamer {
helpstr="usage: renamer {add} <findCoarsePat> <oldStr> <addToOldStr>"
helpstr="$helpstr\n"'Just `add` for right now. More options coming soon!'
if [ $# -ne 4 ]; then
1>&2 printf "$helpstr\n"
return 1
fi
if [ "$1" = "add" ]; then
shift
find . -name "$1" -exec rename.ul -v "$2" "$2 $3" '{}' \;
elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
1>&2 printf "$helpstr\n"
return 0
fi
}
# shortcut for making script-files
function mkscript {
touch "$1"
chmod a+x "$1"
vim "$1"
}
# Move current working directory up one or more levels:
function up {
rungnum=1 # how many ladder-rungs to climb, default just 1 level if no args
path="`pwd`"
while getopts ":S123456789" opt; do
if [[ "$opt" == "S" ]]; then
path="`pwd -P`"
shift # allow rungnum to be picked up as $1 below
elif [[ "$opt" == '?' ]]; then
echo 'up usage: up [-S] [levels]'
echo 'levels specifies how many times to go up a directory.'
echo -n '-S does an absolute ascent (resolves symbolic links in path)'
kill -INT $$
fi
done
if (( $# > 0 )); then
rungnum=$1
fi
declare -a ladder
while [ "$path" != "/" ]; do
ladder+=("$path")
path=`dirname "$path"`
done
dest="${ladder[$rungnum]}"
if [[ ${#ladder[@]} -gt $rungnum ]]; then
# if a valid rung per the array-size was specified:
cd "$dest"
else
# if caller wanted a level higher than the highest level, just put them at
# system root:
cd "/"
fi
}
# recursive grep / grep recursive
function grepr {
# NOTE: to allow this function to work in readonly directories,
# ..... the "~" ($HOME) directory is used to write a temporary file.
# ..... On Windows systems, the default $HOME path is generally not set
# ..... correctly, resulting in errors when `grepr` is called.
# ..... This can be resolved either by using CMD's mklink
# ..... to create a symbolic link in [cygwinDirectory]/home to the proper place
# ..... (on Windows 7 and up), or you can directly set $HOME in /etc/bashrc,
# ..... ~/export_local, or elsewhere that individual ".bashrc"s are likely to
# ..... source.
location=$"." #"`pwd -P`"
regex=$""
findargs="-type f"
dostring=""
if (( $# < 1 )); then
echo 'Recursive grep usage: grepr <regex> or grepr <location> <regex> [<args for find>]'
echo 'With the simple invocation, find will receive -type f. With the full invocation, this must be specified if desired.'
kill -INT $$
elif [[ $# -eq 1 ]]; then
# if we just got the one argument
regex="$1"
dostring="grep -R -n -H '$regex' . --color=always "
else # (( $# > 1 )); then
# if we got more than one argument
location=$"$1"
regex=$"$2"
findargs=$""
shift 2
while [[ $# -gt 0 ]]; do
if [[ "$1" == -type ]]; then
# if we're dealing with the -type flag, assume it's followed by a letter:
findargs=$"$findargs $1"
shift
findargs=$"$findargs $1" # find will choke if passed e.g. -type 'f' vs. -type f
elif [[ "$1" == -* || "$1" == \! ]]; then
# if component begins with '-' or is negator '!'
# don't quote so it actually reads as a flag:
findargs=$"$findargs $1"
else
# otherwise quote so that we don't get glob-expansion happening early:
findargs=$"$findargs '$1'"
fi
shift
done
dostring=$"find $location $findargs -exec grep -n -H '$regex' {} --color=always \\;"
fi
# find $location $findargs -exec grep -H '$regex' {} --color=always \\\;
fn=$"/tmp/`whoami`_grepr_`date +%s`.tmp"
echo "$dostring" > "$fn"
chmod u+x "$fn" # enable execution for current user
. "$fn" # execute file in current shell
rm -f "$fn"
}
# [ Complex alias for builtin `ps` command ]
function ps {
if (( $# == 2 )) && [[ "$1" == "aux" ]]; then
psResults=$"`command ps aux`"
echo "$psResults" | awk 'NR==1'
echo "$psResults" | grep "$2"
else
command ps "$@"
fi
}
# [ Complex alias for vim invocation ]
function vim {
if (( $# == 1 )) && [[ "$1" = *:* ]]; then
# if given a grep-style path followed by a colon giving a
# line-number, automatically separate the two and jump to that line:
command vim "${1%:*}" -c "${1#*:}"
return $?
fi
command vim "$@"
return $?
}
# [ Complex alias for git to add options depending on the specifc subcommand ]
function git {
if (( $# > 0 )); then
if [[ "$1" == "commit" ]]; then
if printf 'scale=2;%s - 2.9\n' "$(git --version | cut -d' ' -f3 | cut -d'.' -f1,2)" | bc | grep -q '^-' && [[ "$(git config core.hooksPath)" != "" ]]; then
oldIFS="$IFS"
IFS='
'
git_root="$(git rev-parse --show-toplevel)"
configured_hookspath="$git_root/$(git config core.hooksPath)"
default_hookspath="$git_root/.git/hooks"
for f in $(ls -1 --color=never "$configured_hookspath"); do
f="$configured_hookspath/$f"
basef="$(basename "$f")"
if ! diff -N >/dev/null "$f" "$default_hookspath/$basef"; then
command cp -f "$f" "$default_hookspath"
fi
done
IFS="$oldIFS"
fi
# Always run our custom pre-commit script before committing:
bash -c ". ~/bin2/githooks/pre-commit" && command git "$@"
if (( $? == 0 )); then
# if a commit was just made, show the author-information afterwards
# so that misattributed commits can be caught before being pushed
# to repo:
command git show | awk 'NR==2'
fi
elif [[ "$1" == "clone" ]]; then
command git "$@" --recursive
elif [[ "$1" == "cd" ]]; then
cd "$(git rev-parse --show-toplevel)"
elif [[ "$1" == "add" && $# = 1 ]]; then
# `git add` by itself assumes interactive, just like `git commit` does:
command git add -i
else
command git "$@"
fi
else
command git
fi
}
# Write to the beginning of a file
function prepend {
if (( $# < 2 )); then
echo "Two or more arguments required. Usage: prepend <prefix> file1[ file2...]"
echo ""
echo "Note that since this command is a wrapper for sed, characters such as"
echo "backslashes require double-escaping, once for the shell and once"
echo "again for sed; for one backslash to be included in the prepended"
echo "output string, the substring \\\\\\\\ (four backslashes) must"
echo "appear in the input to the command."
else
prefix=$"$1"
shift # move past the prefix so all remaining params are files
while (( $# > 0 )); do
sed -i "1i $prefix" "$1"
shift
done
fi
}
# Delete the contents of a file
function nuke {
if (( $# < 1 )); then
echo 'One or more arguments required. Useage: nuke file1[ file2...]'
echo 'Overwrites file(s) with an empty regular file.'
kill -INT $$
fi
for a in "$@"; do
rm "$a"
touch "$a"
done
}
function hashdeebhide {
sed -i 's/^\([ \t]\+\)\([^ #].* # PRODREM\)/\1# \2/' "$1"
}
# Uncompress tar'd files:
function untar {
if (( $# < 1 )); then
echo 'No arguments received. Usage: untar <archiveFile>'
else
tar -zxvf "$1"
if (( $? != 0 )); then
echo Unpack failed under gzip. Trying again with bzip2.
tar -jxvf "$1"
fi
fi
}
# Remove vim lockfiles
function unlock {
if (( $# < 1 )); then
echo 'No arguments received. Usage: unlock <file>'
else
for arg in "$@"; do
# ^ loop through arguments as needed
if [[ "$arg" = .* ]]; then
# if argument starts with a dot, vim doesn't add another:
rm "$arg".swp
else
rm ."$arg".swp
fi
done
fi
}
# Change current working directory to the absolute directory of a symlink
function cdl {
cd "$(dirname "$(readlink "$1")")"
}
# Alias for cdl function (defined above)
function lcd {
cdl "$@"
}
# Convert a Windows-style file-path to a linux-style one
function wcd {
cd $(echo "$1" | sed 's/\\\\/\//g')
}
# Change current working directory to a parallel directory
sis() {
cd "$(\cis "$@")"
}
# usage: sis [<index>] <replacement> [<path>]
# index -- the index of the path-component to replace, where 1
# represents the first component of the path.
# Negative numbers can be used to count from the deepest part
# of the path. -1 is the name of the current directory
# Defaults to: -1
#
# replacement -- the value of the path-component (directory) found at <index>
# which should replace whatever is currently there
#
# path -- the path to work on
# Defaults to: current directory
cis() {
part=-1 # index of component to change
path="`pwd`"
if [[ $# -gt 2 ]]; then
path="$3"
fi
OLDIFS="$IFS"
sub="$1" # string to use for replacing target index
IFS='/'
IFS=/ read -ra patharr <<< "$path"
if [ $# -gt 1 ]; then
if printf '%s' "$1" | grep -q '^[-+]\?[0-9]'; then
part="$1"
sub="$2"
fi
fi
if [ $part -eq 0 ]; then
1>&2 echo "0 is not a valid index. 1 is the first, -1 is the last."
return 1
fi
slot=$part
if [ $part -lt 0 ]; then
slot=$((${#patharr[@]}+$part))
fi
patharr[$slot]="$sub"
printf '%s' "${patharr[*]}"
IFS="$OLDIFS"
}
# [ Complex alias for builtin `du` command ]
function duc {
# below, we ignore aliases on `du` with `command`
if (( $# < 1 )); then
command du -h -s *
else
command du -h "$@"
fi
}
# Output a table of contents for a zip-file:
function toc {
if (( $# < 1 )); then
echo 'toc function - exports a table of contents for a zip-file'
echo "\tUsage: toc <file>.zip"
fi
vim -c "w $1.toc" -c "q" "$1"
echo "Saved toc to $1.toc"
}
function xviml {
# view the contents of an xml-file after formatting has been applied
if (( $# < 1 )); then
echo 'Format XML and open in vim. Saving afterwards optional. Usage: xviml <file>'
kill -INT $$
fi
xmllint "$1" --format | vim -
}
function sviml {
# view the contents of an SQL-file after keywords have all been capped
if (( $# < 1 )); then
echo 'Format PostgreSQL and open in vim. Saving afterwards optional. Usage: sviml <file>'
kill -INT $$
fi
# vim "$1" -c 'call ChangeSqlCase()'
vim "$1" -c 'normal ggVG:call ChangeSqlCase()'
# ^ gg goes to top
# ^.. V starts selecting by line
# ^.. G goes to bottom
# ^.. Then we call a custom function to fix the case and hit enter
}
function jsonf {
if (( $# < 1 )); then
echo "Format JSON-file in-place."
kill -INT $$
fi
t="$(mktemp)"
python -m json.tool "$1" "$t"
mv -f "$t" "$1"
}
function jvimn {
# view the contents of a JSON-file after formatting has been applied
if (( $# < 1 )); then
echo 'Format JSON and open in vim. Saving afterwards optional. Useage: jvimn <file>'
kill -INT $$
fi
formatted="$(python -m json.tool "$1")"
rcode=$?
if [[ $rcode -eq 127 ]]; then
1>&2 echo 'jvimn: Problem finding `python` command.'
elif [[ $rcode -eq 0 ]]; then
printf "%s" "$formatted" | vim -c "setlocal syntax=json" -c "file $1" -
else
1>&2 echo "jvimn: Something went wrong when trying to format the JSON."
1>&2 echo "jvimn: Please check the file at: $1"
fi
}
function headlessql {
# start psql in a loop that listens forever to a FIFO file
if [ $# -lt 1 ]; then
1>&2 echo "headlessql warning: no connection-information given."
fi
if [ "$PGPASSWORD" = "" ]; then
printf 'PGPASSWORD is unset. Set it now?'
read -n 1
if [ "$REPLY" = "y" ]; then
printf '\nPlease input PGPASSWORD.\n'
read -s
export PGPASSWORD="$REPLY"
echo ""
fi
fi
fifoPath="/tmp/fif"
if [ $# -gt 1 ]; then
fifoPath="$2"
fi
mkfifo "$fifoPath"
while [ 1 = 1 ]; do
# try to disable the pager, since we generally only want to look at the
# window rather than touch it
export PAGER=""
# Pick up latest changes to .headlessqlrc file, since this may be
# modified on-the-fly:
if [ -e ~/.headlessqlrc ]; then
. ~/.headlessqlrc
fi
if [ "$HEADLESSQL_TEE_TARGET" = "" ]; then
HEADLESSQL_TEE_TARGET="/dev/null"
fi
# run with `-q` first so there isn't a bunch of spam from the target
# psqlrc file (assuming it's present) every time we loop, but then turn
# quiet off again after it's sourced so we can see output:
PSQLRC="~/.headlessql_psqlrc" psql "$1" -q -v VERBOSITY=default \
-v QUIET=off --expanded -v ON_ERROR_STOP=on -v ON_ERROR_ROLLBACK=on \
-f "$fifoPath" 2>&1 \
| sed \
-e '/^Null display is ".*"/d' \
-e '/^\\set ECHO/d' \
-e '/^--/! s/^.*/-- \0/' \
| tee -a "$HEADLESSQL_TEE_TARGET" \
| sed 's/^-- //'
# ^ the last sed command here before we reach `tee` finds all lines
# that don't have the SQL comment leader and then adds it to those
# lines. The sed command AFTER `tee` strips it off again so the
# immediate output looks nicer.
done
# socket-approach is simpler to express because it doesn't require a loop
# but at least for psql, a bad SQL-command will break it, so that doesn't
# fly. Anyways for posterity, here's what it looks like:
# socketPath="/tmp/sock"
# socat UNIX-LISTEN:"$socketPath",fork STDOUT | psql "$1" 2>&1
}
function fnd {
# If given a single search-term, do a sliding search in the current directory
# assume contains-search first:
term='*'"$1"'*' # potentially nonfinal
if (( $# == 0 )) || (( $# > 2 )); then
echo 'shortfind usage: fnd [-e] <term>'
echo '-e -- exact match'
kill -INT $$
elif (( $# == 2 )); then
if ! [[ "$@" = *-e* ]]; then
echo -e "\nTo use two arguments with shortfind, one must be -e"
echo 'For more information just use fnd by itself to show help'
kill -INT $$
elif [[ "-e" = $1 ]]; then
term="$2"
elif [[ "-e" = $2 ]]; then
term="$1"
fi
fi
command find . -iname "$term"
}
function c_d {
if (( $# > 0 )) && [ "$1" != "-" ] && ! [ -d "$1" ]; then
local parentDir=$(dirname "$1")
echo "$1 is not a directory." 1>&2
if [[ -d "$parentDir" ]] && [[ "$parentDir" != "." ]]; then
# ^ dirname yields "." if passed the empty string. Since "." should
# pretty invariably test as a valid directory, we check for this
# separately. We can encounter this if the caller does a relative `cd`
# like `cd 0` in a directory where there is no subdir called '0'
echo "Changing to parent dir instead." 1>&2
command cd "$parentDir"
fi
return 1;
else
command cd "$@"
return $?;
# ^ `command` is transparent to operations encountering errors, so we
# just go by what it tells us
fi
}
# Shortcut for doing both `chown` and `chgrp`
function choth {
usr="`whoami`"
if (( $# > 1 )); then
usr="$1"
shift
fi
for arg in "$@"; do
chown "$usr" "$arg"
chgrp "$usr" "$arg"
done
}