Pages

Showing posts with label GNU/Linux. Show all posts
Showing posts with label GNU/Linux. Show all posts

Wednesday, September 5, 2012

Touché 0.3 Released!

Another couple of weeks, another major release!
This time with more interesting features I hope.
First of all, now Touché is a KDE only application, no more dual releases with Qt-only version. Of course, this may disappoint someone, but this allowed me to add some nice new features, like Global Shortcuts for profile switching.
And profiles themself were improved too, both fixing small problems, and adding a "Default" profile, when no other profile is available.
Default profile will also provide a "fallback action" if some key is not configured on the selected profile, this way you can enable an action on multiple profiles without having to copy it.

Main menu was refactored a bit, It's nicer and much more well organized.

Code was refactored as well, which lead us to an API for adding new "device modules", not just HID devices.

And we have a living example too: Wiimote support. You can easly setup a Wiimote as remote control by just enabling it in the "Configure Touché" menu entry, "Modules section", then by just connecting it. Currently it supports every physical button on the wiimote; I plan to add some other nice stuff too as gestures.

As usual, source tarball is available on github download page.
More downloads and information in Touché Homepage

Tuesday, August 28, 2012

How to install System Rescue CD + rEFInd in an USB Stick for EFI systems (Macboot, UEFI PC/Laptops)

update: with further reading of rEFInd website, I could find a better way to specify more options with only one menu entry. The configuration section was subsequently updated.

This blogpost comes in handy mostly if you have an EFI system (Apple Macbook, but also some Intel based desktops and laptops), and you need a portable USB stick for emergency booting.
I've been using System Rescue CD for a long time now, it's probably one of the best  rescue tools around.
It's a live Linux distribution that can help restoring not only Linux installations, but Windows and OSX too, has gparted as a partitioning tool, can restore bootloaders (such as grub), has network support and ssh server (so you can use rsync to copy filesystem, control it remotely, browse the web to search for help if you panic) but being a live linux distro it may be used in almost every way you like. You may give a look to their homepage to see details.
It can also be installed in an USB stick, which comes quite in handy as you don't have to carry a relatively big support as a CDRom; nowadays usb sticks are cheap, small and fairly reliable, I always carry with me a SystemRescue usb stick for emergency repairs.

It might however be problematic using it if you have an EFI/UEFI based system, since SystemRescue CD doesn't actively support it.
For instance, in a macbook you can boot a system rescue cd, but not from usb stick, as the EFI system can boot usb sticks only if they contains an EFI bootloader.
Which is just annoying if you have a macbook pro, but becomes a real problem if you have a Macbook Air, as they don't have a CDROM Reader.

Another tool I've recently discovered is rEFInd Boot Manager, which is an EFI bootloader capable of discovering other EFI bootloaders. Beside being an excellent bootloader it can also be used as a rescue tool, since it might boot your system if your installed bootloader has been misconfigured.

Since rEFInd can directly boot Linux kernels too, if they're compiled using EFISTUB option (version >= 3.4), and since System Rescue CD does itself contain a 3.4 kernel, can this help us, combining both of these tools in a single USB Stick?

Of course the answer is yes!

Let's see how.

First, download System Rescue CD, and install it on the USB Stick using these  instructions.
Now download rEFInd too, just choose the CD-R Image File on their download page.
Extract rEFInd CD-R Image copying all the files into the USB Stick.
Open /EFI/boot/refind.conf and modify it as follows:

  • find the "scanfor" commented out line, and add this one (uncommented, of course):
    scanfor manual,internal,external,optical,hdbios,biosexternal,cd
  • At the end of the file, add the following lines (you may replace "it" with your favourite keymap):
menuentry "System Rescue CD x64" {
        icon /EFI/boot/icons/os_linux.icns
        loader /syslinux/altker64
        initrd /syslinux/initram.igz
        options "scandelay=5"
        submenuentry "IT Keyboard, cache" {
          add_options "setkmap=it docache add_efi_memmap"
        }
        submenuentry "IT Keyboard, cache, noapic" {
          add_options "setkmap=it docache noapic add_efi_memmap irqpoll acpi=force"
        }
        submenuentry "IT Keyboard, nocache" {
          add_options "setkmap=it"
        }
        submenuentry "IT Keyboard, nocache, noapic" {
          add_options "setkmap=it  noapic add_efi_memmap irqpoll acpi=force"
        }
        submenuentry "No EFI" {
          add_options "noefi"
        }
        submenuentry "VGA" {
          add_options "vga=791"
        }
}


And... that's it! We're done! Just try it out, rEFInd will show you the three System Rescue CD options, and the other installed operating systems.
You may of course customize kernel boot arguments with the options supported by System Recue CD.

As an optional step, since EFI is supported manily on x64 machines (that's why I've only added x64 kernel boot options) you may safetly remove the various "*ia32*" files you may see around, which should be "shellia32.efi", "refind/drivers_ia32", "refind/refind_ia32.efi", "EFI/boot/drivers_ia32", "EFI/boot/bootia32.efi".

Note: if you have one of the awful new Macbook pro/retina/air, which have serious problems booting linux, you may want to add the options "add_efi_memmap noapic" to properly boot System Rescue CD with EFI. I have already included it in one of the submenus.

Thursday, August 23, 2012

Touché 0.2

Hello folks? Back from vacation?
I am, and so is Touché, with a second major release!

The most important change in this version is the addition of profiles, meaning you can have multiple bindings configured for each device, and you can switch them by context menu.
This release also features many code reworks, GUI and backend fixes and refactorings opening the way to future new features.

Here's the full changelog:


  • Ported build system to CMake
  • Added profiles, to have different bindings for the same keys
  • Major code cleanup, allowing to add more engines (next one probably will be Wiimote)
  • Cleaning up desktop file and appName (fixing some issues with encoding)
  • Binding keypress and keyrelease events on "Translate to key" dialog
  • Added "aliases" in keyboard database, so now different device version can be mapped to the same key (example: apple remote)

Now the bad news: both the keyboard database file and the configuration file have changed.
The first one won't bother you, unless you've defined a custom keyboard mapping file. In this case, please contact me, I can help you fixing it, and it can also be added to the default keyboard database file.

For the configuration, it's much easy to migrate it:
  • cd $HOME/.config/GuLinux
  • mv Touché.conf Touche.conf # I renamed it, to avoid encoding issues
  • now open Touche.conf with your favourite text editor, and replace "[bindings]" with "[bindings_Default]" (or bindings_YourDesiredProfileName).
That's it!
Just enjoy the new release, and don't be shy! Feedback is welcome!


More downloads and information in Touché Homepage

21:27 (GMT+2) Update: there was a small issue with the configuration GUI. I modified source code to fix the problem. Please download again and rebuild the package if you have any inconvenience.

Friday, July 13, 2012

Macbook pro 2012 (8.1) e Ubuntu

Apple: un passo avanti, 10 indietro (come al solito).
All'arrivo dei nuovi macbook aziendali (perchè usare un mac in azienda, poi?) mi sono meravigliato di un notevole miglioramento del sistema operativo più antipatico e chiuso del mondo: una volta ripartizionare la partizione di sistema di OSX era veramente complicato. Oggi invece è possibile farlo anche dallo stesso sistema operativo: innovazione non da poco, credo che su linux si possa fare solo con btrfs.

Ma veniamo alle rogne: provo la "solita" procedura di installazione, usando Refit perchè ok, grub "dovrebbe" supportare il boot efi nativo, ma si sa, io non mi fido mai molto...

Occhio a selezionare il "partizionamento manuale".
Come layout del disco scelgo il seguente:
  • sda1: partizione EFI di osx (già esistente).
  • sda2: partizione di sistema osx (già esistente).
  • sda3: partizione di recovery di osx (già esistente).
  • sda4: swap linux, dimensioni pari alla ram del sistema (nel mio caso, 4GB)
  • sda5: partizione root linux (non mi andava di creare mille partizioni, ed ho messo tutto sulla root, potrò sempre cambiare in seguito).
Accorgimento importante: in una delle schermate di installazione viene chiesto dove installare il boot loader (grub2). Io ho scelto la partizione root linux (quindi /dev/sda5), e a parte le rogne di OSX che descriverò in seguito la cosa è andata liscia. Un'alternativa (da testare) potrebbe essere sda1.

Il primo boot è andato senza problemi. Una cosa che però mi ha stranizzato quasi subito è stata la scomparsa di refit.
Dopo un paio di riavvii decido di riavviare osx per verificare il funzionamento di alcune periferiche. E qui iniziano i problemi.
Anzitutto, grub2 non riesce ad avviare osx. Probabile qualche incompatibilità con lion.
Cercando su google la soluzione migliore sembra essere di avviare il mac tenendo premuto il tasto "option" (che è evidentemente il modo fighetto dei mac-isti di chiamare il tasto "ALT").

Ok, osx si avvia... problema: ha sovrascritto senza pietà grub, infatti al riavvio successivo è impossibile avviare ubuntu.
Ri-ok, pazienza, proviamo a installare refit: risultato, refit NON viene mostrato (mi sa che viene sovrascritto anche lui) e in più non si avvia più neanche osx.
Ri-ri-ok: una soluzione che riesco a trovare è di installare refit su un cdrom. Questo riesce a far avviare sia osx sia linux.
Ma ovviamente bisogna metterci una pezza.
Ecco come sono riuscito a rimediare:

Al primissimo avvio di Ubuntu, in /etc/grub.d/ creare un nuovo file per inserire una entry "custom" in grado di avviare OSX.
Nel mio caso, /etc/grub.d/42_osx_chainloader
Ricordarsi di marcarlo come eseguibile (chmod a+x /etc/grub.d/42_osx_chainloader).
Il contenuto è il seguente:

#!/bin/sh
cat <<EOF
# Chainloading OSX EFI Bootloader
menuentry "OSX-Chainloader" {
        insmod part_gpt
        insmod hfsplus
        set root='(hd0,gpt2)'
        search --no-floppy --fs-uuid --set=root $( grub-probe -d /dev/sda2 -t fs_uuid)
        load_video
        set do_resume=0
        chainloader /usr/standalone/i386/boot.efi
}120
EOF

Ovviamente se OSX non fosse su /dev/sda2 bisogna modificare inserendo il dispositivo giusto (ma su una installazione di default dovrebbe andar bene).

Eseguire "sudo update-grub"
Al prossimo boot, troverete la nuova entry "OSX-Chainloader". Sceglierla per avviare osx.
Adesso il problema è evitare di far sovrascrivere grub da osx.
Io ho risolto scrivendo un file che reimposta grub come bootloader di default.
Posizione: /usr/sbin/bless_grub.sh
#!/bin/bash
mkdir -p /Volumes/efi
mount -t msdos /dev/disk0s1 /Volumes/efi

bless --folder=/Volumes/efi --file=/Volumes/efi/EFI/ubuntu/grubx64.efi --setBoot
bless --mount=/Volumes/efi --file=/Volumes/efi/EFI/ubuntu/grubx64.efi --setBoot



Anche questo file deve essere marcato come eseguibile (chmod a+x /usr/sbin/bless_grub.sh ).
Ora bisogna fare in modo di far eseguire questo file ad osx come root ad ogni avvio.
La soluzione "pulita" è usare plist, l'init di apple. Essendo abbastanza complesso da usare, ho optato per la soluzione "quick&dirty", ovvero aggiungere la riga
 /usr/sbin/bless_grub.sh
Alla fine del file /etc/rc.common.
Abbiamo finito: adesso grub2 è in grado di avviare osx, ed osx ad ogni avvio reimposta grub2 come bootloader predefinito.
Unico problema ancora aperto: nel mio caso grub2 ci mette ben 20 secondi ad avviarsi.
Idee?
Update: aggiornando a Ubuntu 12.10 beta (e quindi presumibilmente anche grub) il problema sembra sparito...
Update-bis: ho notato che a risolvere non è stato l'aggiornamento, infatti il problema si è ripresentato.   Pensandoci meglio però ho trovato la soluzione effettiva: rieseguire "grub-install", senza parametri.

Saturday, May 19, 2012

Touché 0.1.1


New minor release available for Touché, mostly for build and bug fixes.
Here's the changelog:

  • Make build more reliable.
  • Desktop file fixed for kdeinit launch error.
  • Use of kuniqueapplication in release mode (no need for multiple instances).
  • Fix crash when removing a device with configuration dialog open.
  • Microsoft Wireless Keyboard 3000: added "F-Block" key mapping.


Source tarball: http://github.com/rockman81/Touche/downloads
Arch Linux packages (AUR):

Ubuntu packages:


Friday, May 11, 2012

Touché 0.1 Release!

After a week or so of both developing and testing, I am finally able to present a fully featured 0.1 release!
A lot of work has been done, comparing to the first "proof of concept" version.
Most notably, a configuration user interface!
Here's the full changelog:
  • Catch input event from /dev/usb/hiddevX, otherwise ignored by the system.
  • Json Devices Database: pretty easy syntax for adding new devices. Both Qt (simpler) and KDE (stilish) main applications are supported.
  • Fully configurable by a simple user interface.
  • Provides an udev rule to easly fix permissions on your usb devices.
  • Automatically configures xmodmap to bind your unrecognized keys.
  • Full support for Microsoft Wireless Keyboard 3000 (a.k.a. Microsoft Wireless Destkop 3000); possibly similar variants too.
  •  Support for Apple IR remotes (old MacBook pro tested); there are different variants, two of them are configured right now.
Source tarball available here: http://github.com/rockman81/Touche/downloads
Arch linux packages (AUR):


Touché in action

Thursday, May 3, 2012

Touché: special key recognizer for Linux Desktops

a.k.a. Make your extra keyboard keys "just work".
read me first: apparently planet kde linked only this post from backlog instead of newer ones.
You can see more updates about Touché (including first two "stable" releases) here:
http://rockman81.blogspot.it/p/touche.html

I always loved having some spare extra keys in my input devices.

Contrary to Apple's philosophy, which every year tries to remove some keyboard or mouse button here and there, just because "user might be scared! too much stuff to handle!", i find quite more simple to just press the "Play" button on my keyboard to start my audio player, or "Next" to skip to the following song, or "ZoomIn" to enlarge browser fonts, and so on.

It's also quite more productive, in my point of view: for instance i use a lot virtual desktops, therefore i can "switch context" just by switching desktop (for instance, desktop 1: internet; desktop 2: console apps; desktop 3: instant messaging; desktop 4: application development). And what's faster? Typing "CTRL+Shift+F2" (if you can remember it!) to switch to desktop 2, or just having a mouse with an extra button, binded to the (in my opinion, beautiful) desktop grid effect?
One button click, and you're directly here:


I can even remember that when i used to play Quake 3 Arena, my mouse with two extra lateral buttons gave me a fair advantage on my enemies, allowing me to fast-switch to the "most useful" weapons.

Therefore, as you might imagine, i always try to buy keyboards (and mices) with lots of extra keys. But as some of you might have experienced, not all of them do work.

My last purchase is a Microsoft Wireless Keyboard 3000: not so bad, it has lots of extra keys, the bundled mouse has 4 extra buttons (other than the standard 3 ones and the wheel), and most of the extra keys do work out of the box.

But "most of them" is not enough.


I never could get to work the "Flip Window" key  (bottom-right), nor the "12345*" keys, next to the standard multimedia keys. I barely could have the "ZoomIn-ZoomOut" keys (left), because i noticed that they were captured as joypad events (joypad? Wtf?)

So, after some research i noticed that all these keys do generate an event, in the special device "hiddev0".
And i wrote an application to read them: Touché.

It's still in heavy development, it lacks a configuration utility, and currently it supports only my keyboard model, but it's probably easly configurable to support other keyboards, if they do generate events in hiddev too.
And beside what's missing, it's already fully functional: it can both translate your special key to a Xorg recognized key, or run a custom command.

If you want your keyboard supported, you can inspect the application output (with the command line argument "--dump-events"), and contact me to get support.

Build instruction included in the README file.
Feedback is welcome :)

Thursday, August 21, 2008

Estetica Bash

Da così...
#!/bin/bash
found_in_application_xml=$(grep ProjectName /bea/one/9/923/apps/BEdomain/BHcluster/ear/h2o/BHapp/app/META-INF/application.xml)
if [ -n "$found_in_application_xml" ]; then
echo "/bea/one/9/923/apps/BEdomain/BHcluster/ear/h2o/BHapp/app/META-INF/application.xml: OK"
else
echo "/bea/one/9/923/apps/BEdomain/BHcluster/ear/h2o/BHapp/app/META-INF/application.xml: ProjectName not found"
sed -i 's/<\/application>/<module><ejb>ejb\/ProjectName\/ejb20_BH_ProjectName_81.jar<\/ejb><\/module>\n<\/application>/' /bea/one/9/923/apps/BEdomain/BHcluster/ear/h2o/BHapp/app/META-INF/application.xml
fi
found_in_log4j=$(grep projectname /bea/one/9/923/system/BEdomain/BHcluster/log4j.properties)
if [ -n "$found_in_log4j" ]; then
echo "/bea/one/9/923/system/BEdomain/BHcluster/log4j.properties: OK"
else
echo "/bea/one/9/923/system/BEdomain/BHcluster/log4j.properties: projectname not found"
echo "
log4j.appender.PROJECTNAME=org.apache.log4j.FileAppender
log4j.appender.PROJECTNAME.File=/log/projectname.log
log4j.appender.PROJECTNAME.layout=org.apache.log4j.PatternLayout
log4j.appender.PROJECTNAME.layout.ConversionPattern=[%t] [%d{DATE}] - %c -%p: %m%n
log4j.logger.it.sella.projectname=INFO, PROJECTNAME" >> /bea/one/9/923/system/BEdomain/BHcluster/log4j.properties
fi
found_in_integrazione_sistemi_esterni_properties=$(grep ProjectName /bea/one/9/923/system/BEdomain/BHcluster/subSystem.properties)
if [ -n "$found_in_integrazione_sistemi_esterni_properties" ]; then
echo "/bea/one/9/923/system/BEdomain/BHcluster/subSystem.properties: OK"
else
echo "/bea/one/9/923/system/BEdomain/BHcluster/subSystem.properties: ProjectName not found"
echo "
#<ProjectName>
Service.SomeSystem.serviceType=ejb
Service.SomeSystem.xmlStrategy=./data/ProjectName/subsystem.xml
Service.TestSomeSystem.serviceType=ejb
Service.TestSomeSystem.xmlStrategy=./data/ProjectName/ise/ise_TestSomeSystem.xml
#</ProjectName>" >> /bea/one/9/923/system/BEdomain/BHcluster/subSystem.properties
fi
found_in_do_post_contabilizzazione_properties=$(grep projectname /bea/one/9/923/system/BEdomain/BHcluster/OtherSubSystem.properties)
if [ -n "$found_in_do_post_contabilizzazione_properties" ]; then
echo "/bea/one/9/923/system/BEdomain/BHcluster/OtherSubSystem.properties: OK"
else
echo "/bea/one/9/923/system/BEdomain/BHcluster/OtherSubSystem.properties: projectname not found"
echo "
#<ProjectName>
DEB03=it.home.projectname.lib.Class
DEB05=it.home.projectname.lib.Class
#</ProjectName>
" >> /bea/one/9/923/system/BEdomain/BHcluster/OtherSubSystem.properties
fi


a così:
#!/bin/bash
PROJECTNAME="ProjectName"
BEADIR="/bea/one/9/923"

BH_JAR_NAME="ejb20_BH_${PROJECTNAME}_81.jar"
MODULEPATH="ejb/$PROJECTNAME/"

APPLICATION_XML="${BEADIR}/apps/BEdomain/BHcluster/ear/h2o/BHapp/app/META-INF/application.xml"

LOG4JFILE="${BEADIR}/system/BEdomain/BHcluster/log4j.properties"
DOPOSTFILE="${BEADIR}/system/BEdomain/BHcluster/OtherSubSystem.properties"
ISEFILE="${BEADIR}/system/BEdomain/BHcluster/subSystem.properties"



function searchIn() {
FILE="$1"
SUBSTRING="$2"
GREPOPTS="$3 $4 $5 $6 $7 $8 $9"
grep -q $GREPOPTS $SUBSTRING $FILE
return
}

function stringForSed() {
echo "${1//\//\\/}"
}

function addEjbModuleToXml() {
MODULE=$1
XMLFILE=$2
APPLICATION_TAG="</application>"
EJB_TAG="<module><ejb>$MODULE</ejb></module>"
sed -i "s/$(stringForSed $APPLICATION_TAG)/$(stringForSed $EJB_TAG)\n$(stringForSed $APPLICATION_TAG)/g" $XMLFILE
}

function log4j_properties() {
FILENAME="$1"
cat >>"$FILE" <<EOF
log4j.appender.PROJECTNAME=org.apache.log4j.FileAppender
log4j.appender.PROJECTNAME.File=/log/projectname.log
log4j.appender.PROJECTNAME.layout=org.apache.log4j.PatternLayout
log4j.appender.PROJECTNAME.layout.ConversionPattern=[%t] [%d{DATE}] - %c -%p: %m%n
log4j.logger.it.sella.projectname=INFO, PROJECTNAME
EOF
}

function subSystem_properties() {
FILENAME="$1"
cat >>"$FILE" <<EOF
#<ProjectName>
Service.SomeSystem.serviceType=ejb
Service.SomeSystem.xmlStrategy=./data/ProjectName/subsystem.xml
Service.TestSomeSystem.serviceType=ejb
Service.TestSomeSystem.xmlStrategy=./data/ProjectName/ise/ise_TestSomeSystem.xml
#</ProjectName>
EOF
}

function OtherSubSystem_properties {
FILENAME="$1"
cat >>"$FILE" <<EOF
#<ProjectName>
DEB03=it.home.projectname.lib.Class
DEB05=it.home.projectname.lib.Class
#</ProjectName>
EOF
}


if ! searchIn "$APPLICATION_XML" "$BH_JAR_NAME"; then
echo "Adding $BH_JAR_NAME in $APPLICATION_XML"
addEjbModuleToXml "$MODULEPATH/$BH_JAR_NAME" $APPLICATION_XML
fi


for FILE in $LOG4JFILE $DOPOSTFILE $ISEFILE; do
if ! searchIn "$FILE" $PROJECTNAME "-i"; then
appenderName="$(basename "$FILE")"
echo "Updating $FILE..."
${appenderName//./_} "$FILE"
fi
done

Thursday, July 17, 2008

Actions handler via filesystem monitoring

Avendo avuto la necessità di eseguire degli script bash che eseguono il riavvio di servers Weblogic senza avere a disposizione una shell da cui lanciarli abbiamo pensato le più disparate possibilità, ivi compreso smanettare tutto il giorno sulla console di Weblogic, progettare applicazioni standalone jmx, pagine jsp apposite.. oggi pomeriggio mi sono reso conto che in realtà tutto ciò che serve è un crontab funzionante.
Basta creare uno script shell lanciato ripetutamente da quel crontab (tipo ogni minuto) e che controlla l'esistenza di determinati files per lanciare azioni ad essi associate (e cancellare il file che ha scatenato l'azione).
Durante qualche ritaglio di tempo nelle pause ecco cos'è uscito fuori:
#!/bin/bash                  

#ACTIONSDIR="/tmp/actions"
ACTIONSDIR="/nodel/actions"
ACTIONSCRIPTSDIR="$ACTIONSDIR/scripts"
ACTIONS="restart-admin restart-batch crontab"

function doAction() {
action="$1"
actionfile="$ACTIONSDIR/$action"
actionscript="$ACTIONSCRIPTSDIR/${action}.sh"
if [ -r $actionfile.lock ]; then return; fi
echo "`date`: running action $action with script file $actionscript" > $actionfile.lock
echo "doing action $action (script file: $actionscript)"
chmod +x $actionscript
$actionscript $action $actionfile
rm $actionfile
rm $actionfile.lock
}

function createDir() {
dirToCreate=$1
if [ -d $dirToCreate ]; then
return
fi
mkdir -p $dirToCreate
}

createDir $ACTIONSDIR
createDir $ACTIONSCRIPTSDIR

for action in $ACTIONS; do
actionfile=$ACTIONSDIR/$action
if [ -r $actionfile ]; then
doAction $action &
fi
done



Un paio di commenti:
  • Per aggiungere/rimuovere azioni basta modificare la variabile ACTIONS e aggiungere gli script nella directory adeguata (specificata da ACTIONSCRIPTSDIR)
  • gli script vengono lanciati in maniera asincrona dal loop principale, ma in maniera sincrona nel doAction, in modo tale da cancellare il file di lancio solo dopo il termine dello script. Un file di lock impedisce di rilanciare l'azione se è ancora in esecuzione.
  • Il file di lancio viene passato come argomento (insieme al nome dell'azione) allo script. Questo permette di inserire un target come "crontab", che potrebbe essere usato per aggiornare il crontab appunto leggendo dal file di lancio il nuovo cron da installare.

Saturday, July 12, 2008

Fast Scripting Tool

Spesso per risolvere determinati problemi d'ordine quotidiano mi capita di creare piccolo script shell appositi, da buon maniaco della linea di comando.
La procedura per creare uno script può risultare relativamente noiosa: creare un file con touch, renderlo eseguibile con chmod, modificarlo col proprio editor preferito, specificare in cima l'interprete ("#!/bin/bash" di solito)... ed è sempre la stessa solfa, piuttosto pallosa.
Soluzione: mi sono scritto uno script bash per creare altri script bash.
Ho anche fatto in modo di parametrizzarlo: il primo parametro è lo script da creare, il secondo l'interprete (opzionale, se non specificato di default va su "/bin/bash".
Ecco lo script, da piazzare magari in /usr/local/bin in modo da averlo nel path:
#!/bin/bash
function usage() {
echo "Usage: `basename $0` filename [interpreter path]"
exit 0
}


if test "x$1" == "x"; then
usage
fi

INTERPRETER="/bin/bash"

if test "x$2" != "x"; then
if ! [ -r $2 ]; then
echo "Error! Interpreter \"$2\"not found"
usage
else
INTERPRETER="$2"
fi
fi

cat >$1 <<EOF
#!$INTERPRETER

EOF

chmod +x $1
vim $1 +2




L'ultima riga in particolare apre vim, specificandogli anche su che riga piazzarsi.. per la precisione dopo la seconda, subito dopo la dichiarazione dell'interprete (così non si fa neanche la fatica di premere freccia-giù :P)