Написание интерпретатора сценариев в bash

#linux #bash #unix #netbsd

#linux #bash #unix #netbsd

Вопрос:

Я написал оболочку bash для ruby, которая проходит различные этапы настройки.

Самая базовая версия,

    #!/bin/bash 
   #   ruby_wrapper.sh
   ruby
  

Теперь я хочу иметь возможность использовать эту оболочку так же, как обычный ruby! В частности, я хочу создать файл .rb, который использует этот «интерпретатор».

    #!/path/to/ruby_wrapper.sh
   #  my_file.rb
   puts "hello world"
  

Итак, я хочу иметь возможность делать $ ./my_file.rb вместо $ ruby_wrapper.sh my_file.rb

Возможно ли это?

В документации утверждается, что это не так.

Обратите внимание, что интерпретатор сам по себе может не быть сценарием интерпретатора.

Но я не понимаю, почему нет. Есть ли у кого-нибудь идеи, как обойти это?

Комментарии:

1. Документация, на которую вы ссылаетесь и цитируете, предназначена для NetBSD, а не для Linux.

2. Верно, но то же самое верно и для Linux. kernel.org/doc/man-pages/online/pages/man2/execve . 2.html > Интерпретатор должен иметь допустимый путь к исполняемому файлу, который сам по себе не является скриптом.

Ответ №1:

Попробуйте вызвать свою оболочку с помощью /usr/bin/env . На самом деле хорошей практикой является выполнение скриптов Ruby с помощью /usr/bin/env ruby , поскольку вам не нужно жестко кодировать путь к ruby двоичному файлу, так что в этом нет ничего противоестественного.

 $ cat ruby_wrapper.sh 
#!/bin/bash
exec ruby "$@"

$ cat wrapped.rb 
#!/usr/bin/env /tmp/ruby_wrapper.sh
puts "hello world"

$ ./wrapped.rb 
hello world
  

Также в качестве дополнительного примечания посмотрите, как я использовал exec в скрипте-оболочке. Это позволит интерпретатору ruby управлять процессом вашего скрипта-оболочки, а не запускаться как дочерний процесс вашего скрипта. Это делает оболочку прозрачной для вызывающего (сигналы будут доставляться непосредственно на ruby, а не на bash, например).

Комментарии:

1. Отлично, спасибо! Я читал о том, что для переносимости используется трюк /usr / bin / env, но не понимал, что это позволит обойти это ограничение.