You are not logged in.
NTP client in 2 actual lines of code, plus some pretty wrapping paper:
#!/bin/bash
[[ $UID -ne 0 ]] && { echo "Error: Must be root!" >&2; exit 1; }
clockset() {
echo "Setting hwclock to localtime from time.nist.gov..."
hwclock --set --date="$(awk '{if (NF > 1) print $2,$3 " UTC"}' < /dev/tcp/time.nist.gov/13)" || return 1
echo "Sync'ing hwclock to system..."
hwclock -s
echo "The time is now:" $(hwclock)
return 0
}
clockset
Could probably use some error reporting if/when the net redirect explodes.
Offline
NTP client in 2 actual lines of code
Explain how this works, please. Mainly the '< /dev/tcp/time.nist.gov/13' part.
/etc/rc.d/ is where daemons reside. Beware.
Offline
It's purely a Bashism.
Offline
This works great ...
#!/bin/sh
#
# screenrec.sh: POSIX sh based screen recorder that relies on scrot and mencoder.
# You also need bc, and your `sleep` must support floats.
#
. "$HOME"/.scripts/common_stuff.sh
rtfm(){ echo rtfm; exit 1; }
test $# -eq 2 || rtfm
file="$1"; shift
dur="$1"; shift
test_ints "$dur" || rtfm
test $dur -gt 0 || rtfm
make_tmp_dirs imgdir || exit 2
stopat=$(($(date +%s)+$dur))
for i in $(seq -w 1 99999)
do
scrot "$imgdir"/$i.png
test $(date +%s) -ge $stopat && break
done
fps=$(echo "scale=3; $(ls "$imgdir" | wc -l)/$dur" | bc)
mencoder mf://"$imgdir"/* -mf fps=$fps -o "$file".avi -ovc lavc -lavcopts vcodec=mpeg4 > /dev/null 2>&1
rm -f "$imgdir"/*
... for ~1 FPS screen recording.
``Common sense is nothing more than a deposit of prejudices laid down by the mind before you reach eighteen.''
~ Albert Einstein
Offline
Not very useful without your common_stuff source
[git] | [AURpkgs] | [arch-games]
Offline
Well it's obvious what the functions do, and it's the concept that matters, but anyway; here's the current version of common_stuff.sh:
(Edit: Obsolete and breakage-prone.)
#!/usr/bin/printf This file is meant to be sourced!\n\c
#
# common_stuff.sh: Some useful functions and stuff for shell scripts.
#
progname="$(basename "$0")"
validate_var_names ()
{
for var
do
if
test "$(echo "$var" | wc -l)" -ne 1 ||
echo "$var" | grep -q '\(^[0-9]\|[^a-zA-Z0-9_]\)'
then
return 1
fi
done
}
default ()
{
validate_var_names "$1" || return 255
eval 'test "$'$1'" || '$1'="$2"'
}
test_ints ()
{
for int
do
test "$int" -eq "$int" 2> /dev/null || return 1
done
}
test_files ()
{
local test_args="$1"; shift
local tests=true
for i in $(seq 1 ${#test_args})
do
tests="$tests && test -$(echo "$test_args" | cut -c $i) \$file"
done
for file
do
eval $tests || {
echo >&2 "$progname: problem related to file: $file"
return 1
}
done
}
# This trapping mechanism is the shit
make_trap ()
{
echo "$1" | grep -q '[^A-Z]' && return 255
eval '
'$1'file="${TMPDIR:-/tmp}"/$progname-$1file-$$
touch "$'$1'file" || {
echo >&2 "$progname: could not create file: $'$1'"
return 1
}
trap'$1'(){ echo >> "$'$1'file" "$@"; }
trap'$1' "#!/bin/sh"
trap'$1' "rm -f \"\$0\""
chmod u+x "$'$1'file"
trap "\"$'$1'file\"" $1
'
}
make_trap EXIT # Initialize this right away; it's very common
# Other functions even assume it to be existant
make_tmp_files ()
{
for file
do
validate_var_names "$file" || return 255
eval '
'$file'="${TMPDIR:-/tmp}"/$progname-$file-$$
trapEXIT "rm -f \"$'$file'\""
touch "$'$file'" || {
echo >&2 "$progname: could not create file: $'$file'"
return 1
}
'
done
}
make_tmp_dirs ()
{
for dir
do
validate_var_names "$dir" || return 255
eval '
'$dir'="${TMPDIR:-/tmp}"/$progname-$dir-$$
trapEXIT "rmdir \"$'$dir'\" 2> /dev/null"
mkdir -p "$'$dir'" || {
echo >&2 "$progname: could not create directory: $'$dir'"
return 1
}
'
done
}
touch_files ()
{
for file
do
>> "$file" || {
echo >&2 "$progname: could not create file: $file"
return 1
}
done
}
touch_dirs ()
{
for dir
do
mkdir -p "$dir" || {
echo >&2 "$progname: could not create directory: $dir"
return 1
}
done
}
random_num ()
{
test_ints "$@" || return 255;
local min=${1:-0}
local max=${2:-$(($min+32767))} # Default max of Bash
seq $min $max | shuf | head -n 1
}
Last edited by TaylanUB (2010-06-06 09:09:50)
``Common sense is nothing more than a deposit of prejudices laid down by the mind before you reach eighteen.''
~ Albert Einstein
Offline
test_ints () { for int do test "$int" -eq "$int" 2> /dev/null || return 1 done }
Huh? I don't quite get that... What's the point there?
[git] | [AURpkgs] | [arch-games]
Offline
test_ints () { for int do test "$int" -eq "$int" 2> /dev/null || return 1 done }
Huh? I don't quite get that... What's the point there?
The test fails if "int" is not an arithmetic value.
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
Oh LOL, i just now realize it's really not obvious from the function definition; you're supposed to pass the function a variable (which is expanded before the function receives it as an argument) so you can test if a variable holds an integer or not.
It's really the same as doing a `test "$var" -eq "$var" 2> /dev/null` manually, but using the function is much cleaner and can be done to many variables at once. You see me use it in the other post.
@skanky: `test` strictly awaits _integers_ for its numerical functions. stderr is redirected to /dev/null because it actually prints an error if you try to give it a float.
Last edited by TaylanUB (2010-05-05 13:40:08)
``Common sense is nothing more than a deposit of prejudices laid down by the mind before you reach eighteen.''
~ Albert Einstein
Offline
Ahh, that I didn't know. That's comment-worthy I think
[git] | [AURpkgs] | [arch-games]
Offline
@skanky: `test` strictly awaits _integers_ for its numerical functions. stderr is redirected to /dev/null because it actually prints an error if you try to give it a float.
Wasn't sure is it accepted floats or not (I know $((...)) is integer only), but it will also give you an error message if $int is a character.
Anyway, have just checked and confirmed what you say.
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
//blue/0/~/ test_int() { [[ -z "${1//[0-9]/}" ]]; }
//blue/0/~/ test_int 8
//blue/0/~/ test_int 5.7
//blue/1/~/ test_int ack
//blue/1/~/
note: "$1" is expected to be non-null in the above.
Last edited by brisbin33 (2010-05-05 14:18:36)
//github/
Offline
@Daenyth: Agreed. I think i should comment more often in general.
@skanky: Oh right, stderr needs to be redirected either way.
@brisbin: That one 1) depends on a Bashism, 2) won't accept negative integers, 3) fails on a null-string (as you said), 4) is just few characters shorter when you add the for loop.
Last edited by TaylanUB (2010-05-05 14:57:18)
``Common sense is nothing more than a deposit of prejudices laid down by the mind before you reach eighteen.''
~ Albert Einstein
Offline
@brisbin: That one 1) depends on a Bashism, 2) won't accept negative integers, 3) fails on a null-string (as you said), 4) is just few characters shorter when you add the for loop.
yes, all valid points. personally, i always write for bash so the built-in [[ is better than spawning a separate test process. i typically handle null variables specifically, and i hadn't run into the need to test for negatives yet...
anyways, just offering another approach, not bash(pun!)ing yours .
//github/
Offline
I don't really get the point in making sh-compatible scripts unless you have a specific target in mind... What *doesn't* have bash?
[git] | [AURpkgs] | [arch-games]
Offline
@skanky: Oh right, stderr needs to be redirected either way.
Yes, agreed. Never said otherwise.
As for coding for sh, doesn't that mean that the script can run in a number of other shells? A mate of mine works on a load of bashless Unix systems at work. Obviously though, whether he wants to keep his scripts portable depends on what it does, but he generally tries to keep the general ones portable. For me personally, I tend to not bother except maybe make a note in the comments if I suspect something that may bite one day (eg awk version, or specific application required, or I'm going to share it).
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
I don't really get the point in making sh-compatible scripts unless you have a specific target in mind...
I agree.
What *doesn't* have bash?
busybox uses ash.
Offline
Hence "specific target". Stuff that you intend to run on a desktop linux machine... not so much. Targeting for busybox is different of course.
[git] | [AURpkgs] | [arch-games]
Offline
Regarding me, it's really somewhat of an obsession with minimality.
Pretty much no one else than me will use these scripts, in first place.
Although, how much do you really benefit from learning a huge amount of extra functionality, when you can probably do the same thing by maybe writing half a line more code, and invoking a second binary?
`man bash` is a bit more than 3 times the size of `man dash` (BSD sh manpage).
POSIX could even get rid of ${foo:?bar}, ${foo:+bar}, etc., or even the ${foo%bar} stuff for all i care; test, sed and expr have a purpose!
Except, is there a sane way to achieve ${foo#bar} with sed? I'm either missing something or it requires some crufty regexing. Though i'm not exactly serious with that last part; i'm sure there's a few useful things that POSIX could take from bash or even zsh.
Last edited by TaylanUB (2010-05-05 17:08:53)
``Common sense is nothing more than a deposit of prejudices laid down by the mind before you reach eighteen.''
~ Albert Einstein
Offline
Really simple script that randomly changes my wallpaper on demand (xbindkeys). When starting my WM, it's put into the background again (wp). Works great no matter what WM I'm currently using unless it's KDE or e17 I guess.
dir=$DATA_DIR'/pics/wallpapers/'
file=`/bin/ls -1 "$dir" | sort --random-sort | head -1`
path=`readlink --canonicalize "$dir/$file"`
feh --bg-scale $path
cp $path ~/.config/wp
Last edited by Zoranthus (2010-05-05 17:17:16)
Offline
POSIX could even get rid of ${foo:?bar}, ${foo:+bar}, etc., or even the ${foo%bar} stuff for all i care; test, sed and expr have a purpose!
The thing is though, that sed et al will all require calls to exec() which increases overhead and slows down the script. Using a builtin will run much faster. You also don't have to rely on gnu sed for example, where the system might have bsd userland.
[git] | [AURpkgs] | [arch-games]
Offline
If you cant do it in Ed, or TECO, don't do it at all
[So far as I know, every sane *nix/*bsd has at least one of those]
Offline
POSIX requires vi also
[git] | [AURpkgs] | [arch-games]
Offline
A system for creating a modular action menu in bash.
#!/bin/bash
MODULES_DIR=dir/
declare -A menustrings
for mod in "$MODULES_DIR"/*.mod; do
. $mod
unset modname
done
echo 'Enter the number of your choice (Ctrl+D to exit)'
PS3='Action? '
select action in "${!menustrings[@]}" Exit; do
if [[ $action == Exit ]]; then
break
fi
runmod="${menustrings["$action"]}"
${runmod}_run
done
# foo.module
modname=foo
menuitem='Run foo'
menustrings["$menuitem"]="$modname"
${modname}_run() {
echo "Ran foo!"
}
[git] | [AURpkgs] | [arch-games]
Offline
these are some of the things i have in my bashrc, findin is good, use it all the time, basically does a grep -r except it doesn't bring up svn control files
svnup and svnstat are for doing a update or stat on every folder in the current dir, good for updating a workspace
alias svnup='for DIR in `ls`; do if [ -e "${DIR}/.svn" ] ; then echo -e "updating \E[32m${DIR}\033[0m" ; svn up $DIR ; fi done;'
alias svnstatus='for DIR in `ls`; do if [ -e "${DIR}/.svn" ] ; then echo -e "status for \E[32m${DIR}\033[0m" ; svn status $DIR ; fi done;'
function findin(){
find . | grep -v '.svn' | xargs grep -in --color=auto "$1"
}
Offline