سؤال

الأسئلة:

  • ماذا نواة تفعل إذا كنت عصا قذيفة النصي في كوخ الخط ؟
  • كيف نواة تعرف أي مترجم على الاطلاق ؟

تفسير:

مؤخرا أردت أن أكتب التفاف حول /usr/bin/env لأن CGI بيئة لا تسمح لي أن تعيين المسار متغير, إلا عالميا (والتي بالطبع سيء!).

حتى ظننت, "حسنا.دعونا تعيين PREPENDPATH وتعيين المسار في التفاف حول الحياة الفطرية.".مما أدى النصي (يسمى هنا env.1) يشبه هذا:

#!/bin/bash
/usr/bin/env PATH=$PREPENDPATH:$PATH $*

التي يبدو أن العمل.راجعت كم هم كل من رد بعد وضع PREPENDPATH:

$ which /usr/bin/env python
/usr/bin/env
/usr/bin/python

$ which /usr/bin/env.1 python
/usr/bin/env
/home/pi/prepend/bin/python

نظرة على الاطلاق مثالية!جيد جدا حتى الآن.ولكن انظر ماذا يحدث "مرحبا العالم!".

# Shebang is #!/usr/bin/env python
$ test-env.py
Hello World!

# Shebang is #!/usr/bin/env.1 python
$ test-env.1.py
Warning: unknown mime-type for "Hello World!" -- using "application/*"
Error: no such file "Hello World!"

أعتقد أنا في عداد المفقودين شيء جميل الأساسية عن يونيكس.

أنا جدا المفقودة حتى بعد النظر في التعليمات البرمجية المصدر الأصلي env.فإنه يحدد البيئة تطلق برنامج (أو هكذا يبدو لي).

هل كانت مفيدة؟

المحلول

أولا وقبل كل شيء ، يجب أن نادرا جدا استخدام $* و يجب دائما تقريبا استخدام "$@" بدلا من ذلك.هناك عدد من الأسئلة هنا حتى التي تشرح وعموميات من السبب.

الثانية - env الأمر قد يستخدم.واحد هو طباعة البيئة الحالية ؛ والآخر هو السيطرة تماما على بيئة الأمر عندما يتم تشغيله.الاستخدام الثالث الذي كنت يدل إلى تعديل البيئة ، ولكن بصراحة هناك حاجة لذلك - قذائف قادرة تماما على التعامل مع ذلك لك.

الوضعية 1:

env

الوضعية 2:

env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args

هذا الإصدار يلغي كل ورثت متغيرات البيئة و يعمل command مع دقة البيئة التي وضعتها ENVVAR=قيمة الخيارات.

النمط الثالث - تعديل البيئة - هو أقل أهمية لأنه يمكنك أن تفعل ذلك بشكل جيد مع العادية (المتحضر) قذائف.(التي تعني "لا" ج "شل" - مرة أخرى ، هناك أسئلة أخرى بشأن ذلك مع الإجابات التي تفسر ذلك.) على سبيل المثال ، يمكنك جيدا القيام به:

#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "$@"

هذا تصر على أن $PREPENDPATH يتم تعيين غير فارغة في البيئة ، ومن ثم prepends إلى $PATH, و الصادرات مسار جديد الإعداد.ثم باستخدام هذا الطريق الجديد, ينفذ python برنامج مع الحجج ذات الصلة.على exec يستبدل قذيفة النصي مع python.لاحظ أن هذا يختلف تماما عن:

#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "$@"

ظاهريا هذا هو نفسه.إلا أن هذا سيتم تنفيذ python الاطلاع على القائمة من قبل الطريق ، وإن كان ذلك مع قيمة جديدة من مسار في عملية البيئة.لذلك ، في سبيل المثال ، كنت في نهاية المطاف تنفيذ الثعبان من /usr/bin وليس واحد من /home/pi/prepend/bin.

في الوضع الخاص بك, أنا ربما لا تستخدم env و أن مجرد استخدام البديل المناسب من النص مع صريح التصدير.

على env الأمر غير عادية لأنها لا تعترف مزدوجة اندفاعة إلى خيارات منفصلة عن بقية الأوامر.هذا هو في جزء منه لأنه لا يأخذ العديد من الخيارات ، في جزء منه لأنه ليس من الواضح ما إذا كان ENVVAR=قيمة الخيارات يجب أن تأتي قبل أو بعد double dash.

في الحقيقة لدي مجموعة من البرامج النصية تشغيل (إصدارات مختلفة من) خادم قاعدة البيانات.هذه البرامج النصية حقا استخدام env (و مجموعة نابعة من البرامج) للسيطرة على البيئة من الملقم:

#!/bin/ksh
#
# @(#)$Id: boot.black_19.sh,v 1.3 2008/06/25 15:44:44 jleffler Exp $
#
# Boot server black_19 - IDS 11.50.FC1

IXD=/usr/informix/11.50.FC1
IXS=black_19
cd $IXD || exit 1

IXF=$IXD/do.not.start.$IXS
if [ -f $IXF ]
then
    echo "$0: will not start server $IXS because file $IXF exists" 1>&2
    exit 1
fi

ONINIT=$IXD/bin/oninit.$IXS
if [ ! -f $ONINIT ]
then ONINIT=$IXD/bin/oninit
fi

tmpdir=$IXD/tmp
DAEMONIZE=/work1/jleffler/bin/daemonize
stdout=$tmpdir/$IXS.stdout
stderr=$tmpdir/$IXS.stderr

if [ ! -d $tmpdir ]
then asroot -u informix -g informix -C -- mkdir -p $tmpdir
fi

# Specialized programs carried to extremes:
#   * asroot sets UID and GID values and then executes
#   * env, which sets the environment precisely and then executes
#   * daemonize, which makes the process into a daemon and then executes
#   * oninit, which is what we really wanted to run in the first place!
# NB: daemonize defaults stdin to /dev/null and could set umask but
#     oninit dinks with it all the time so there is no real point.
# NB: daemonize should not be necessary, but oninit doesn't close its
#     controlling terminal and therefore causes cron-jobs that restart
#     it to hang, and interactive shells that started it to hang, and
#     tracing programs.
# ??? Anyone want to integrate truss into this sequence?

asroot -u informix -g informix -C -a dbaao -a dbsso -- \
    env -i HOME=$IXD \
        INFORMIXDIR=$IXD \
        INFORMIXSERVER=$IXS \
        INFORMIXCONCSMCFG=$IXD/etc/concsm.$IXS \
        IFX_LISTEN_TIMEOUT=3 \
        ONCONFIG=onconfig.$IXS \
        PATH=/usr/bin:$IXD/bin \
        SHELL=/usr/bin/ksh \
        TZ=UTC0 \
    $DAEMONIZE -act -d $IXD -o $stdout -e $stderr -- \
    $ONINIT "$@"

case "$*" in
(*v*) track-oninit-v $stdout;;
esac

نصائح أخرى

يجب أن تقرأ بعناية مقالة ويكيبيديا عن كوخ.

عندما يرى النظام الرقم السحري المقابلة تلك لا execve على مسار معين بعد كوخ ويعطي السيناريو نفسه حجة.

البرنامج النصي الخاص بك فشل لأن الملف تعطي (/usr/bin/env.1) لا قابل للتنفيذ, ولكن يبدأ بنفسه قبل كوخ....

من الناحية المثالية, هل يمكن حلها باستخدام... env في السيناريو الخاص بك مع هذا الخط بمثابة كوخ:

#!/usr/bin/env /usr/bin/env.1 python

فإنه لن ينجح ولو على لينكس كما يعامل "/usr/bin/env.1 python"كمسار (لا تقسيم الحجج)

وبالتالي فإن الطريقة الوحيدة أرى أن الكتابة الخاصة بك env.1 في ج

تحرير:يبدو أن لا أحد صدق بأن لي ^^, حتى لقد كتب بسيطة القذرة env.1.c:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


const  char* prependpath = "/your/prepend/path/here:";

int main(int argc, char** argv){
  int args_len = argc + 1;
  char* args[args_len];
  const char* env = "/usr/bin/env";
  int i;

  /* arguments: the same */
  args[0] = env;
  for(i=1; i<argc; i++)
    args[i] = argv[i];
  args[argc] = NULL;

  /* environment */
  char* p = getenv("PATH");
  char* newpath = (char*) malloc(strlen(p)
                 + strlen(prependpath));
  sprintf(newpath, "%s%s", prependpath, p);
  setenv("PATH", newpath, 1);

  execv(env, args);
  return 0;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top