From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Pascal Bourguignon Newsgroups: gmane.emacs.help Subject: Re: Cool and Useful LISP for the .emacs file Date: 12 Nov 2003 19:21:19 +0100 Organization: [posted via Easynet Spain] Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Message-ID: <873cctih28.fsf@thalassa.informatimago.com> References: <7ik76b4k7s.fsf@neoscale.com> <87oevn9mim.fsf@141-moc-9.acn.waw.pl> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1068664641 27688 80.91.224.253 (12 Nov 2003 19:17:21 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 12 Nov 2003 19:17:21 +0000 (UTC) Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Nov 12 20:17:17 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AK0UP-0006K8-00 for ; Wed, 12 Nov 2003 20:17:17 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AK1RN-0006n1-0H for geh-help-gnu-emacs@m.gmane.org; Wed, 12 Nov 2003 15:18:13 -0500 Original-Path: shelby.stanford.edu!newsfeed.stanford.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!colt.net!easynet-quince!easynet.net!easynet-post2!not-for-mail Original-Newsgroups: gnu.emacs.help User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 Original-Lines: 407 Original-NNTP-Posting-Host: 62.93.174.79 Original-X-Trace: DXC=TZ70B[I?[oGLU4]bMB;U2MSiHWb3f14:CbBd4DjF1d]A Original-Xref: shelby.stanford.edu gnu.emacs.help:118174 Original-To: help-gnu-emacs@gnu.org X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.help:14115 X-Report-Spam: http://spam.gmane.org/gmane.emacs.help:14115 David Masterson writes: > >>>>> Artur Hefczyc writes: > > > Kin Cho writes: > >> I used to carry around a collection of shell, sed, awk, and perl > >> scripts to do various text/file/directory processing, as well as > >> doing cvs/rcs stuff, running compilation and gdb etc... Now I do > >> (almost) all these things in elisp. > > > I like this idea! I would like to use elisp as scripting language > > also. However I would like to know if it is possible to use it that > > way. I mean, lets assume I create elisp script to update my Linux box > > system with new releases of some packages. > > > Is it possible to run it from command line like all other scripts, > > bash, perl etc.? > > > I mean file script starting from: > > #!/usr/bin/emacs > > > Or any other elisp interpreter? > > Given how big Emacs is, I would think that it would be best to start > emacs in background (say, from your .login) and then use something > like gnudoit or emacsclient to send your elisp to the background > Emacs. Done correctly, I would think that it would execute your > scripts much faster, no? No. emacs IS NOT big. $ ls -l emacs perl -rwxr-xr-t 1 pascal regular 4433296 2003-11-12 19:08 emacs* -rwxr-xr-x 1 pascal regular 1113248 2003-11-12 19:08 perl* emacs is already in core memory so forking additionnal emacs processes does not cost anything significant. Starting a script in perl or in emacs takes the same time. (Any time below 0.7 s IS the same time). #!/bin/bash echo ================================================= time emacs -batch -no-site-file -q \ -eval '(progn (message "Hello from emacs") (kill-emacs))' echo ================================================= time clisp -q -ansi -norc \ -x '(progn (format t "Hello from clisp!~%") (ext:quit))' echo ================================================= time sbcl --noinform --noprint --sysinit /dev/null --userinit /dev/null \ --eval '(progn (format t "Hello from sbcl!~%") (SB-EXT:QUIT))' echo ================================================= echo '(display "Hello from scsh\n") ,exit' | bash -c 'time scsh' echo ================================================= time perl -e 'printf "Hello from perl\n";exit' echo ================================================= exit 0 ./script-times ================================================= Hello from emacs real 0m0.060s user 0m0.040s sys 0m0.010s ================================================= Hello from clisp! real 0m0.023s user 0m0.010s sys 0m0.010s ================================================= Hello from sbcl! real 0m0.024s user 0m0.010s sys 0m0.010s ================================================= Scsh 0.5.3 > Hello from scsh #f > real 0m0.076s user 0m0.030s sys 0m0.020s ================================================= Hello from perl real 0m0.009s user 0m0.000s sys 0m0.000s ================================================= To allow the use of #! for emacs, I implemented this small wrapper: lisp-script.c: ------------------------------------------------------------------------ /****************************************************************************** FILE: lisp-script.c LANGUAGE: ANSI-C SYSTEM: POSIX USER-INTERFACE: POSIX DESCRIPTION This is a simple tool that encapsulate clisp or emacs invokation as script interpreters. USAGE Insert #!/usr/local/bin/emacs-script or #!/usr/local/bin/clisp-script as the first line of a lisp program, and run it. AUTHORS Pascal J. Bourguignon MODIFICATIONS 2003-10-27 Added SBCL. 2002-04-06 Creation. BUGS LEGAL GPL Copyright Pascal J. Bourguignon 2002 - 2003 This file is part of lisp script tools. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ #include #include #include #include #include #ifndef EMACS #define EMACS "/usr/local/bin/emacs" #endif #ifndef CLISP #define CLISP "/usr/local/bin/clisp" #endif #ifndef SBCL #define SBCL "/usr/local/bin/sbcl" #endif #ifdef MACOSX /* Not exactly correct. We should grab GNU dirname/basename.*/ static const char* basename(const char* path) { const char* slash=strrchr(path,'/'); if(slash==0){ return(path); }else{ return(slash+1); } }/*basename*/ #else #include #endif const char* pname="lisp-script"; void usage(const char* pname) { fprintf(stderr, "%s usage:\n"\ " %s -h|--help | script-file [script-arguments...]\n", pname,pname); }/*usage*/ int main(int argc,char** argv) { int i; int length; int position; char* script_file=0; char* script_option; char* init_file; enum { emacs, clisp, sbcl } kind; pname=basename(argv[0]); if(strcmp(pname,"emacs-script")==0){ kind=emacs; }else if(strcmp(pname,"clisp-script")==0){ kind=clisp; }else if(strcmp(pname,"sbcl-script")==0){ kind=sbcl; }else{ lisp_script: fprintf(stderr,"%s: should be invoked either as emacs-script, " "clisp-script or sbcl-script.\n",pname); return(EX_USAGE); } if((strcmp(argv[1],"-h")==0)||(strcmp(argv[1],"--help")==0)){ usage(pname); return(EX_OK); } if(1 (defconst EX_OK 0 "successful termination") (defconst EX__BASE 64 "base value for error messages") (defconst EX_USAGE 64 "command line usage error") (defconst EX_DATAERR 65 "data format error") (defconst EX_NOINPUT 66 "cannot open input") (defconst EX_NOUSER 67 "addressee unknown") (defconst EX_NOHOST 68 "host name unknown") (defconst EX_UNAVAILABLE 69 "service unavailable") (defconst EX_SOFTWARE 70 "internal software error") (defconst EX_OSERR 71 "system error (e.g., can't fork)") (defconst EX_OSFILE 72 "critical OS file missing") (defconst EX_CANTCREAT 73 "can't create (user) output file") (defconst EX_IOERR 74 "input/output error") (defconst EX_TEMPFAIL 75 "temp failure; user is invited to retry") (defconst EX_PROTOCOL 76 "remote error in protocol") (defconst EX_NOPERM 77 "permission denied") (defconst EX_CONFIG 78 "configuration error") (defconst EX__MAX 78 "maximum listed value") (defun ext:exit (&optional status) " DO: stops the script, exiting with the given status. " (unless status (setq status EX_OK)) (kill-emacs status) );;ext:exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Common-Lisp / Elisp (defun read-line (&optional input-stream eof-error-p eof-value recursive-p) " DO: Implement partially Common-Lisp read-line function. " (unless input-stream (setq input-stream standard-input)) (let ( (standard-input input-stream) (line nil) (char (read-char)) ) (while (not (member char '(10 13))) (push char line) (setq char (read-char)) ) (funcall 'concat (nreverse line)) );;let );;read-line (defalias 'EXT:EXIT 'ext:exit) (defalias 'READ-LINE 'read-line) ;;;; emacs-script.el -- 2003-02-08 04:35:08 -- pascal ;;;; ------------------------------------------------------------------------ -- __Pascal_Bourguignon__ http://www.informatimago.com/