You are not logged in.
Offline
I can only encourage you not to use the TLDP guide and rather refer to the guide I posted. TLDP does not teach you bash -- it teaches you how to write buggy shell code and in some cases, is just plain wrong.
Thanks for reminding me to ask why they never pulled it from the website. I've heard complaints about the errors and omissions from a number of people and yet the guide is still there.
I know you can't make them remove it but ...
Offline
I can only encourage you not to use the TLDP guide and rather refer to the guide I posted. TLDP does not teach you bash -- it teaches you how to write buggy shell code and in some cases, is just plain wrong.
I didn't know that. Well i will restart reading from the guide you posted. Thanks for the info
Offline
My script to manage school assignments. It's my first real attempt at writing something using a variety of cmdline utilities.
Offline
A tiny script for quickly figuring out which package owns a binary file that's in the path:
#!/bin/sh
which $1 && pacman -Qo `which $1`
I call it whichowns.
Offline
A tiny script for quickly figuring out which package owns a binary file that's in the path:
#!/bin/sh which $1 && pacman -Qo `which $1`
I call it whichowns.
you know, pacman has this feature built-in now, you can just do `pacman -Qo <binaryfile>` and it will do the path resolving internally.
< Daenyth> and he works prolifically
4 8 15 16 23 42
Offline
O_o I didn't know, thx.
Offline
Hi! I did small, simple and rather straightforward (read shortest route) script to search, list and download .torrent-files from piratebay by plain commandline. It is my first attemp to do something usable and is purely part of my shell scripting learning process, yet see it handy time to time.
#!/bin/bash
#Extremely simple Piratebay torrent download script. At the moment it shows just the first page
#from piratebay search so maximum hits are 30 (still, those are top-hits).
#Uses lynx and wget.
#Usage: pirate -s <search string>
#Config
function config_load {
#Torrent save path
torrentdir="$HOME/torrent"
#Temporary files
piratetmp="$torrentdir/.piratetmp.tmp"
piratefound="$torrentdir/.piratefound.tmp"
piratelinks="$torrentdir/.piratelinks.tmp"
touch $piratetmp $piratefound $piratelinks
}
#Script
function usage {
echo "
Piratebay command line script for searching and downloading torrent files.
Shows 30 most seeded hits.
Usage: pirate -h | --help
pirate -s | --search \"search string\".
Example: pirate -s archlinux
pirate -s without string parameter shows recent additions to site.
Example: pirate -s
"
}
#exit functions
function error_exit {
usage
exit 1
}
function normal_exit {
rm $piratetmp $piratefound $piratelinks
exit 1
}
#Main function
function searchtor {
#load prenamed files
config_load
#downloads first page of searched item and push to file
lynx -source http://thepiratebay.org/search/$sstring >> $piratetmp
##Scripts to analyze downloaded html-stuff
#extracts number of total hits 2
found=`cat $piratetmp |grep 'approx' | cut -d 'x' -f2 |cut -d ' ' -f2`
#extracts nice version of torrent names & push to file
list=`cat $piratetmp |grep "detName" |cut -d ' ' -f7-18 |cut -d '>' -f1 |cut -d '"' -f1 >> $piratefound`
#linenumbers for found torrents
foundlist=`nl $piratefound`
#extracts links to torrents & push to file
foundlinks=`cat $piratetmp |grep 'http://torrents.thepiratebay.org/' |cut -d '=' -f2 |cut -d '"' -f2 >> $piratelinks`
#Outputs
echo "Search hits for $sstring: $found."
echo ""
echo "Torrents:$foundlist"
echo ""
echo "Enter number to download torrent-file."
echo "--------------------------------------"
read tname
if [ "$tname" == "" ]; then
normal_exit
else
torrdown=`cat $piratelinks |sed -n "${tname}p"`
wget -q $torrdown -P $torrentdir
echo Torrent saved to $torrentdir
normal_exit
fi
exit 1
}
# Commandline arguments
while [ "$1" != "" ]; do
case $1 in
-s | --search ) shift
sstring=$@ #stores parameters (search strings)
searchtor
;;
-h | --help ) usage #shows arguments
exit
;;
* ) error_exit
esac
shift
done
Edit. I started to develop this little bastard and I quess it aint this threat to contribute updates so I put it in github. https://github.com/pekkarin/piratec. Yet I'll save the original script here for reference.
Last edited by waldo (2011-10-31 13:09:50)
Offline
A little timer script in ruby. You tell it how long to wait, and once it's done waiting it starts music (with mpd) and sends a notification.
(An "Eieruhr" (a german word) is a little countdown clock that starts ringing after running out, usually used in the kitchen, to have a reminder to get the eggs out of the boiling water when they're done)
#!/usr/bin/ruby
# coding: utf-8
# vim: ft=ruby
# eieruhr
require 'RNotify'
require 'slop'
trap("SIGINT") { exit 0 }
opts = Slop.parse :help => true do
on :s, :seconds, 'Wait for x seconds', :optional => false, :as => :integer
on :m, :minutes, 'Wait for x minutes', :optional => false, :as => :Integer
on :h, :hours, 'Wait for x hours', :optional => false, :as => :Integer
end
class Eieruhr
def initialize(slopts)
@opts = slopts
@message = "Time's over!"
@title = "Eieruhr"
@seconds = 0
@seconds += @opts[:seconds] if @opts[:seconds]
@seconds += @opts[:minutes]*60 if @opts[:minutes]
@seconds += @opts[:hours]*3600 if @opts[:hours]
# which mpd playlist to load
@playlist = "ogi"
end
def sleepit
system("date")
puts "Sleeping for " + @seconds.to_s + " seconds"
sleep @seconds
system("date")
end
def startmusic
# obviously, if you use alsa and not oss there will be another way,
# this ossmix command activates my notebook's built-in speakers
system("(ossmix jack.int-speaker.mode mix2 && mpc clear && mpc load #{@playlist} && mpc play) &>/dev/null")
end
def notify_me
# could be replaced with this:
# system(%q[notify-send -u critical -t 0 Eieruhr "Time's up! "])
# thus removing the dependency on RNotify
Notify.init(@title)
note = Notify::Notification.new(@title, @message, nil)
note.urgency= Notify::Notification::URGENCY_CRITICAL
note.timeout = Notify::Notification::EXPIRES_NEVER
note.show
end
def run
sleepit
startmusic
notify_me
end
end
my = Eieruhr.new(opts)
my.run
# This (exit 0) is necessary since otherwise the script would end with an exit
# status of 1, because we didn't uninit the Notify, nor did we close the notification
# but since we want the notification to be up until clicked away...
exit 0
Ogion
(my-dotfiles)
"People willing to trade their freedom for temporary security deserve neither and will lose both." - Benjamin Franklin
"Enlightenment is man's leaving his self-caused immaturity." - Immanuel Kant
Offline
I'm sure there's probably a bash one-liner for this, but as I seem to be developing a plethora of git repositories scattered throughout my home directory, I came up with this little python script to find and symlink all git repos in $HOME into a single directory (for ease of keeping track...I prefer to not actually keep the git repos in this directory, as to me it makes more sense to organize them differently). It also prints a 'git status -s' for each repo so I can run the script from cron and get a daily email if there are any repos that have been changed and need attention (for example, I may update one of my scripts and forget to commit and push the changes).
#!/usr/bin/env python
"""1. Find all git repos in $HOME and symlink in git_all_repos dir.
2. Prints git status for each repo that's not up-to-date.
Variables:
pattern: name of git directory (typically .git)
ignores: tuple of directories to ignore (directory name only,
not full path)
git_path: path of directory to place symlinks into.
Useful to run from cron to check if any of your git repositories
need attention.
"""
import os
import fnmatch
import os.path
from subprocess import Popen, PIPE, call
ignores = ("My_Ignored_Project_Dir",)
home = os.path.expanduser("~")
git_path = os.path.join(home, ".local/src/git_all_repos/")
pattern = ".git"
def locate(pattern, root, ignores):
"""Locate all directories matching pattern in and below supplied
root directory. Ignores names in 'ignores'.
Returns: generator object.
"""
for path, dirs, files in os.walk(root):
for dirname in fnmatch.filter(dirs, pattern):
nm = os.path.join(path, dirname)
if not [i for i in ignores if i in nm]:
yield nm
def main():
# Create Symlinks
current_links = os.listdir(git_path)
for repo in current_links:
# Remove all current symlinks
os.remove(os.path.join(git_path, repo))
for repo in locate(pattern, home, ignores):
path = os.path.dirname(repo)
args = ["git", "status", "-s"]
res = Popen(args, cwd=path, stdout=PIPE).communicate()[0]
if res:
print("{}:\n {}".format(path, res.decode('utf-8')))
repo_nm = os.path.split(os.path.split(repo)[0])[1]
os.symlink(os.path.dirname(repo), os.path.join(git_path, repo_nm))
if __name__ == '__main__':
main()
Scott
Last edited by firecat53 (2011-10-30 02:16:22)
Offline
I'm sure there's probably a bash one-liner for this
Ask and you shall receive...
find "$HOME" -type d -name .git -prune -exec bash -c 'for repo; do repo=${1%.git}; ln -sf "$repo" "/repo/collection/${repo##*/}"; done' _ {} +
Not quite as detailed as yours... but I kind of like this.
Last edited by falconindy (2011-10-30 02:35:33)
Offline
If you've ever obtained files from Windows users, you may have noticed they like to put whitespace everywhere in the filenames. This makes their files more complicated to process in bash scripts. Not impossible, but complicated and frustrating.
This script will remove that layer of complication by replacing all directory and file name whitespace with a dash, recursively.
Some of the code originated from other places on the web that I don't recall, such as the idea of using the "tr" command. However, pre-existing solutions did not consider how to compensate for easily made errors and did not recurse on subdirectories.
Certainly, the "stripws" helper function can also be stripped out into its own bash script if you don't want recursion.
#! /bin/bash
set -e
# Helper function, really the main machinery that does the actual replacement.
function stripws()
{ :
# If the input includes a path with multiple directory levels,
# naively attempting to strip the whitespace from all levels
# at once will produce problems.
#
# For example, think about what would happen if we ran a command
# that, when expanded, said something like:
# mv "All Shall Perish/A Pure Evil.ogg" "All-Shall-Perish/A-Pure-Evil.ogg"
#
# We prevent such problems by only permitting stripws to run on
# the "basename" part of a path. Entire paths can have whitespace
# removed by recursing on subdirectories.
d=$(dirname "$@")
pushd "$d" > /dev/null
b=$(basename "$@")
newname=$(echo "$b" | tr '[:blank:]' -)
# The test says: only process something that has whitespace in its name.
[[ "$b" != "$newname" ]] && mv -v "$b" "$newname"
popd > /dev/null
}
pushd "$@" > /dev/null
# Process everything in the current directory only.
find ./ -mindepth 1 -maxdepth 1 -print -exec stripws {} \;
# Recurse on subdirectories.
find ./ -mindepth 1 -maxdepth 1 -type d -exec "$0" {} \;
popd > /dev/null
# The above commands don't process the base directory. Do it now.
stripws "$@"
Offline
@/dev/zero:
better yet, use perl-rename
community/perl-rename 1.8-1 [installed]
Renames multiple files using Perl regular expressions.
Offline
Hi Sujoy,
Perhaps you have a point; but if you could construct an argument demonstrating the clear superiority of perl for this purpose, that would be awesome :-)
Offline
Hi Sujoy,
Perhaps you have a point; but if you could construct an argument demonstrating the clear superiority of perl for this purpose, that would be awesome :-)
for example,
find ./ -execdir perl-rename -n 's/\s+//g' '{}' \;
Note: perl-rename -n will only do a dry run, not modify anything. see man perl-rename for more details.
Last edited by sujoy (2011-10-30 09:14:20)
Offline
The function key to toggle the touchpad on my laptop (Lenovo Y560) doesn't work on any Linux distro I tried.
You can bind the following script to any key combo via keyboard shortcuts and toggle away
#!/bin/bash
statevar=`synclient -l |grep TouchpadOff`
currentstate=`echo $statevar |cut -d' ' -f3`
synclient TouchpadOff=$((($((currentstate))+1)%2))
Optionally, you can add a notification for the new state, but since notify-send stacks notifications in Gnome 3 I have it disabled.
if [ "$currentstate" == '1' ];
then
notify-send "Touchpad: Enabled"
else
notify-send "Touchpad: Disabled"
fi
Offline
Optionally, you can add a notification for the new state, but since notify-send stacks notifications in Gnome 3 I have it disabled.
Too bad in Gnome 3 the --expire-time option of notify-send is ignored. In Xfce it works as advertised.
Last edited by rwd (2011-10-31 19:44:34)
Offline
I use sendEmail for the process, my script just lays it out better and can be configured more to send log files and other things.
Obviously it could use more, but this is what I use it for.
For sending log files most of the options could be hardcoded and make the script fully non-interactive.
#####################
#!/bin/bash
#####################
# Author: Aaron 'Lugz' Ankiel
# Script to send mail from command line
# Can be adapted to send log files, send output or numerous things.
# Can be used with any smtp server(GMAIL - smtp.gmail.com:587) #####################
# Can also use a networks exchange server to send mail.
# address is the address your sending from # uname is the username to authenticate on the mail server with
LOGFILE='l0g.log'
ADDRESS='user@gmail.com'
SERVER='smtp.gmail.com:587'
UNAME='user@gmail.com'
rm $LOGFILE
echo 'Enter Account Password: '
read -s PWORD
clear
#echo 'Send From Address: '
#read ADDRESS
echo 'Send To Address: '
read ADDRTO
echo 'Subject: '
read SUBJECT
echo 'Message: '
read MSG
# use file contents for message( log files, etc.)
# echo 'File to use as message: '
# read FEIL
# sendEmail -f -f $ADDRESS -t $ADDRTO -u $SUBJECT -o message-file=$FEIL -s $SERVER -xu $UNAME -xp $PWORD -l $LOGFILE
sendEmail -f "$ADDRESS" -t "$ADDRTO" -u "$SUBJECT" -m "$MSG" -s "$SERVER" -xu "$UNAME" -xp "$PWORD" -l "$LOGFILE"
echo 'Log saved to '"$LOGFILE"
Last edited by Lugz (2011-11-01 20:06:23)
Offline
Wouldn't this be better in the user scripts thread?
Some notes:
Instead of passing in passwords in plaintext, I store my passwords in encrypted files, then use $(gpg -d /path/to/passwd.gpg).
If you run this script in any directory containing the file 'l0g.log', you will delete this file. Maybe you really want that, or maybe you would find it better to specify the full path for your log file.
I would separate concerns a little more by moving the account data into a separate file. This way, you can have multiple accounts set up, and you can change which one you're using just by changing an argument to the script.
Finally, when presenting code for others to use or comment upon, you should tidy up your code by removing lines you've commented out. Comments are for explaining your code.
Offline
The function key to toggle the touchpad on my laptop (Lenovo Y560) doesn't work on any Linux distro I tried.
You can bind the following script to any key combo via keyboard shortcuts and toggle away#!/bin/bash statevar=`synclient -l |grep TouchpadOff` currentstate=`echo $statevar |cut -d' ' -f3` synclient TouchpadOff=$((($((currentstate))+1)%2))
The inner $(()) is redundant. I'd go with:
synclient TouchpadOff=$(( 1 - $(synclient -l | grep TouchpadOff | grep -o '[01]$') ))
Edit: Replace [0-9]\+ with [01], because I really mean it.
Last edited by lolilolicon (2011-10-31 20:15:35)
This silver ladybug at line 28...
Offline
I use sendEmail for the process, my script just lays it out better and can be configured more to send log files and other things.
<snip>
Nice script. In bash one should quote variables like this,
sendEmail -f "$ADDRESS" -t "$ADDRTO" -u "$SUBJECT" -m "$MSG" -s "$SERVER" -xu "$UNAME" -xp "$PWORD" -l "$LOGFILE"
whitespace and other weird things are then contained.
Wouldn't this be better in the user scripts thread?
Why not, seems that was the op's intent anyways. I can split it back out if Lugz wants.
(For posterity, original thread was titled "Command Line Email Made Simple".)
Last edited by fsckd (2011-11-01 00:27:19)
aur S & M :: forum rules :: Community Ethos
Resources for Women, POC, LGBT*, and allies
Offline
achilleas.k wrote:The function key to toggle the touchpad on my laptop (Lenovo Y560) doesn't work on any Linux distro I tried.
You can bind the following script to any key combo via keyboard shortcuts and toggle away#!/bin/bash statevar=`synclient -l |grep TouchpadOff` currentstate=`echo $statevar |cut -d' ' -f3` synclient TouchpadOff=$((($((currentstate))+1)%2))
The inner $(()) is redundant. I'd go with:
synclient TouchpadOff=$(( 1 - $(synclient -l | grep TouchpadOff | grep -o '[01]$') ))
Edit: Replace [0-9]\+ with [01], because I really mean it.
I do it with:
$(synclient -l | grep -q 'Off *= 0') && synclient TouchpadOff=1 || synclient TouchpadOff=0
Offline
lolilolicon: Much nicer. Replaced mine already.
egan: I think lolilolicon's version is more elegant.
Offline
Wouldn't this be better in the user scripts thread?
Some notes:
Instead of passing in passwords in plaintext, I store my passwords in encrypted files, then use $(gpg -d /path/to/passwd.gpg).
If you run this script in any directory containing the file 'l0g.log', you will delete this file. Maybe you really want that, or maybe you would find it better to specify the full path for your log file.
I would separate concerns a little more by moving the account data into a separate file. This way, you can have multiple accounts set up, and you can change which one you're using just by changing an argument to the script.
Finally, when presenting code for others to use or comment upon, you should tidy up your code by removing lines you've commented out. Comments are for explaining your code.
Personally I was just using it as a learning example. I included the commented section so others could see the same thing done with reading from a file and also how easy it would be to read log files. I also included that it is pretty much tailored to how I use it. It definitely could be improved and expanded upon, no arguments there. Only took a few minutes to write and it serves its purpose well.
Thank you for your input.
PS - about the log file, i have the rm command in there for that exact reason.
Last edited by Lugz (2011-11-01 20:04:30)
Offline
Lugz wrote:I use sendEmail for the process, my script just lays it out better and can be configured more to send log files and other things.
<snip>Nice script. In bash one should quote variables like this,
sendEmail -f "$ADDRESS" -t "$ADDRTO" -u "$SUBJECT" -m "$MSG" -s "$SERVER" -xu "$UNAME" -xp "$PWORD" -l "$LOGFILE"
whitespace and other weird things are then contained.
Thank you I edited the part being used to have quotes.
Offline