简体   繁体   中英

How can I source this shell script before starting a rinari console?

In my project, we have a shell script that sets default values for some environment variables. When I try to run rinari-console , I receive an error because the script has not been sourced. Is there a way to make sure rinari sources it, so that when the rails console starts, all the variables have the needed values?

Alright I've been thinkg a bit harder about the question. I've come up with two possible solutions:

Outside Emacs via wrapper

This solution is a bit clumsy, but it should work.

You could create a wrapper script, eg 'emacs-wrapper.sh':

#!/bin/sh
set -a
. YOUR-SCRIPT.sh
emacs

If you launch ./emacs-wrapper.sh, YOUR-SCRIPT.sh will be sourced and Emacs is started after that. The same environment will be visible to Emacs this way. Testing this approach on my machine, I was able to (getenv "var") all variables defined in YOUR-SCRIPT.sh

Nicer: Within Emcas via shell-command

This is IMO a much nicer solution since it runs completely inside Emacs. Makes a call to shell-command-to-string to source your YOUR-SCRIPT.sh. At the end it also dumps that process' environment. This is subsequently added to Emacs' own process-environment:

;; defadvice is optional, you could also just call source-script directly
(defadvice rinari-console (before init-environment activate)
   (source-script "/PATH/TO/YOUR-SCRIPT.sh"))

(defun source-script (script)
   (let ((env (extract-environment script)))
       (mapc 'import-environment-variable (split-string env "\n"))))

(defun extract-environment (script)
   (shell-command-to-string (format "set -a; . %s > /dev/null 2>&1; env" script)))

(defun import-environment-variable (variable-assignment)
   (when (not (or (null variable-assignment) (string= "" variable-assignment)))
      (let* ((key-value-pair (split-string variable-assignment "="))
             (key (car key-value-pair))
             (value (cadr key-value-pair)))
        (setenv key value))))

I verified this approach on my machine as well. All variables defined in YOUR-SCRIPT were also defined in Emacs.

I managed to do what you wanted with a wrapper. Suppose you create a rails project in ~/test . Rinari will try to launch irb by executing the command ~/test/script/console . I created a wrapper named ~/test/script/console.sh :

#!/bin/sh

. ~/test/script/env.sh
~/test/script/console

The wrapper sources your script containing the environment variables and then executes the regular command.

The file ~/test/script/env.sh contains:

export TEST=test

Now to use that wrapper, call rinari-mode with a prefix argument Cu Mx rinari-mode and add a .sh to the end of the proposed command. The environment variable TEST will be set.

You could then create a macro that adds the .sh automatically.

I don't use rinari so there could be better ways to do it, but in principle you can do this to run "YOUR-SCRIPT.sh" before running actual rinari-console command.

(defadvice rinari-console (before run-my-script activate)
  (shell-command "YOUR-SCRIPT.sh"))

See also: http://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html

Well if you wanna source the script, should you be able to do something very similar to what tkf suggested:

(defadvice rinari-console (before run-my-script activate)
  (shell-command ". YOUR-SCRIPT.sh"))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM