ইউনিভার্সাল নোড.জেএস শেবাং?


42

নোড.জেএস আজকাল খুব জনপ্রিয় এবং আমি এটিতে কিছু স্ক্রিপ্ট লিখছি। দুর্ভাগ্যক্রমে, সামঞ্জস্যতা একটি সমস্যা। আনুষ্ঠানিকভাবে, নোড.জেএস ইন্টারপ্রেটারকে কল করার কথা node, তবে ডিবিয়ান এবং উবুন্টু nodejsপরিবর্তে ডেকে একটি নির্বাহী বলা হয়।

আমি বহনযোগ্য স্ক্রিপ্টগুলি চাই যা নোড.জেএস যতটা সম্ভব পরিস্থিতিতে কাজ করতে পারে। ফাইলের নামটি ধরে foo.jsনিলে, আমি সত্যিই স্ক্রিপ্টটি দুটি উপায়ে চালাতে চাই:

  1. ./foo.jsহয় nodeবা nodejsএর মধ্যে থাকলে স্ক্রিপ্টটি চালায় $PATH
  2. node foo.jsস্ক্রিপ্টটিও চালায় (অনুমানকারী ডাকা অনুমান করে node)

দ্রষ্টব্য: xavierm02 এবং আমার উত্তরগুলি একটি বহুভোজী স্ক্রিপ্টের দুটি প্রকরণ। আমি এখনও খাঁটি শেবাং সমাধানে আগ্রহী, যদি এরকম উপস্থিত থাকে।


আমি মনে করি এটির কোনও বাস্তব সমাধান নেই, কারণ বিল্ড সিস্টেমগুলি দ্বারা নির্ধারিতভাবে নির্বিচারে নাম দেওয়ার অনুমতি দেওয়া হয়। পাইথন ইন্টারপ্রেটার আলফেসেন্টৌরির নামকরণ থেকে আপনাকে বিরত রাখে এমন কিছুই নেই, আপনি কেবল সম্মেলনগুলি অনুসরণ করেন এবং এর নাম অজগর রাখেন। আমি nodeআপনার স্ক্রিপ্টের জন্য আদর্শ নাম ব্যবহার করার পরামর্শ দিচ্ছি বা শাইবাংকে সংশোধনকারী এক ধরণের মেক স্ক্রিপ্ট দেওয়ার পরামর্শ দেব ।

@ জি.কায়াল্প রাজনীতি এবং সম্মেলনগুলি বাদ দিয়ে অনেকগুলি দেবিয়ান / উবুন্টু / ফেডোরা ব্যবহারকারী রয়েছেন এবং আমি তাদের জন্য কাজ করে এমন স্ক্রিপ্ট তৈরি করতে চাই। আমি এটির জন্য একটি বিল্ড সিস্টেম সেটআপ করতে চাই না (যে কেউ সেগুলি চালনার আগে শেল স্ক্রিপ্টগুলি তৈরি করে?), না আমি সমর্থন করতে চাই না alphacentauriএবং এ জাতীয়। যদি কোনও এক্সিকিউটেবল বলা হয় nodejs, আপনি 99% নিশ্চিত হতে পারবেন এটি নোড.জেএস। কেন nodejsএবং উভয় সমর্থন না node?
নাচছে

নোডেজ-লিগ্যাসি প্যাকেজটি ইনস্টল করুন। এটির প্রয়োজনের কারণটি হ'ল নামটি খুব অহঙ্কারী জেনেরিক, অন্য কেউ নামটি প্রথমে পেয়েছিলেন। অন্য প্যাকেজটি অবশ্য নামটি ভাগ করতে রাজি ছিল।
user3710044

উত্তর:


54

আমি যে সেরাটি নিয়ে এসেছি তা হ'ল এটি "দ্বি-লাইনের শেবাং" যা সত্যিই একটি বহুভক্ত (বোর্ন শেল / নোড.জেএস) লিপি:

#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

console.log('Hello world!');

প্রথম লাইনটি স্পষ্টতই, বোর্নের শেল শেবাং। নোড.জেএস যে কোনও শেবাংকে এটি আবিষ্কার করে সেটিকে বাইপাস করে, সুতরাং নোড.জেএস সম্পর্কিত এটি একটি বৈধ জাভাস্ক্রিপ্ট ফাইল।

দ্বিতীয় লাইন শেল নো অপ আহ্বান :আর্গুমেন্ট সহ //এবং তারপর executes nodejsবা nodeএই ফাইলটি প্যারামিটার হিসাবে নামে। বহনযোগ্যতার জন্য command -vপরিবর্তে ব্যবহৃত হয় which। কমান্ড প্রতিস্থাপন সিনট্যাক্স $(...)কঠোরভাবে বোর্ন নয়, তাই 1980 এর দশকে আপনি যদি এটি চালনা করেন তবে ব্যাকটিক্স বেছে নিন for

নোড.জেএস কেবল স্ট্রিংকে মূল্যায়ন করে ':'যা কোনও অপ-অপের মতো, এবং বাকী রেখাটি একটি মন্তব্য হিসাবে বিশ্লেষণ করা হয়।

ফাইলটির বাকী অংশগুলি কেবল সাধারণ পুরানো জাভাস্ক্রিপ্ট। execদ্বিতীয় লাইনটি শেষ হওয়ার পরে সাব- শেল প্রস্থান করে, তাই ফাইলটি কখনই শেল দ্বারা পঠিত হয় না।

অনুপ্রেরণার জন্য xavierm02 এবং অতিরিক্ত তথ্যের জন্য সমস্ত মন্তব্যকারীকে ধন্যবাদ!


1
দুর্দান্ত সমাধান। ':'পদ্ধতির বিকল্প হ'ল ব্যবহার করা // 2>/dev/null(যা যা তা nvmকরে): ব্যাশ করা, এটি একটি ত্রুটি ( bash: //: Is a directory), যা পুনঃনির্দেশটি 2>/dev/nullচুপচাপ উপেক্ষা করে; জাভাস্ক্রিপ্ট, পুরো লাইন একটি মন্তব্য হয়ে যায়। এছাড়াও - এবং আমি এটি কোনও সমস্যা আইআরএল হিসাবে প্রত্যাশা করি না - commandএর একটি কৌতূহল রয়েছে যেখানে এটি শেল ফাংশন এবং উপকরণগুলির সাথে প্রতিবেদন করে -v- যদিও এটি আসলে তাদের অনুরোধ করবে না। সুতরাং, যদি আপনি রপ্তানি শেল ফাংশন বা এমনকি alias লেখা (অভিমানী আছে এরকম shopt -s expand_aliases) নামে nodeবা nodejs, জিনিষ ভাঙতে পারে।
mklement0

1
ঠিক আছে, পসিক্স এই দিন সর্বব্যাপী (সোলারিস / বিন / শ ব্যতীত - তবে সোলারিস এটিএটি অ্যান্ড টি কেএস-এর সাথে বাক্সের বাইরে আসে যা পসিক্স সামঞ্জস্যপূর্ণ) এবং মার্কাস কুহান (যুক্তি সহকারে) এটি বন্ধ রাখার পরামর্শ দেন। আইএমএইচও আপনার কখনই এটির দরকার নেই। তবে হ্যাঁ, এটা জন্য যথেষ্ট mksh, bash, dashআধুনিক ইউনিক্স এবং গনুহ সিস্টেমের মধ্যে এবং অন্যান্য শাঁস।
মীরাবিলোস

1
দুর্দান্ত সমাধান; যদিও আরও বেশি পোর্টেবল ব্যবহার করতে হবে #!/usr/bin/env shপরিবর্তে #!/bin/sh(প্রতি en.wikipedia.org/wiki/Shebang_%28Unix%29#Portability )
user7089

2
আমি #!/usr/bin/env sh"আরও পোর্টেবল" হিসাবে বিজ্ঞাপন সম্পর্কে সতর্ক থাকব । সেই একই উইকিপিডিয়া নিবন্ধে বলা হয়েছে "এটি বেশিরভাগ ক্ষেত্রে কাজ করে কারণ পাথ / ইউএসআর / বিন / এনভিটি সাধারণত এনভির ইউটিলিটির জন্য ব্যবহৃত হয় ..." এটি কোনও দুর্দান্ত সমর্থন নয়, এবং আমার ধারণা আপনি খুব /usr/bin/envবেশি ঘন ঘন সিস্টেমে চলে যাবেন my আপনি /bin/shফ্রিকোয়েন্সি মধ্যে কোনও পার্থক্য আছে, ছাড়া সিস্টেমে চালিত ।
শেলডনহ

1
2018 থেকে @ ড্যানসেক হাই, //bin/sh -c :; exec ...দ্বিতীয় লাইনের ক্লিনার সংস্করণটি কী হবে না ?
har-wradim

10
#!/bin/sh
//bin/false || `which node || which nodejs` << `tail -n +2 $0`
console.log('ok');

//bin/false/bin/falseদ্বিতীয় স্ল্যাশটি নোডের জন্য একটি মন্তব্যে রূপান্তরিত করা বাদে একই জিনিস , এবং সে কারণেই এটি এখানে। তারপরে, প্রথমটির ডান দিকটি ||মূল্যায়ন হয়। 'which node || which nodejs'উদ্ধৃতিগুলির পরিবর্তে ব্যাককোটিস সহ নোড আরম্ভ <<করে এবং ডানদিকে যা থাকে তা ফিড করে। আমি //ড্যান্কের মতো শুরু করে একটি ডিলিমিটার ব্যবহার করতে পারতাম , এটি কাজ করত তবে প্রথম দিকে দুটি লাইনই থাকি বলে ক্লিনারটি পরিষ্কার মনে হয় তাই tail -n +2 $0ফাইলটি প্রথম দুটি লাইন বাদে নিজেই পড়তে পেতাম ।

এবং যদি আপনি এটিকে নোডে চালনা করেন তবে প্রথম লাইনটি শেবাং হিসাবে স্বীকৃত এবং উপেক্ষা করা হবে এবং দ্বিতীয়টি একটি লাইন মন্তব্য।

(স্পষ্টতই, সেড প্রথম এবং শেষ লাইন ছাড়াই লেজ মুদ্রণ ফাইলের সামগ্রী প্রতিস্থাপনের জন্য ব্যবহার করা যেতে পারে )


সম্পাদনার আগে উত্তর:

#!/bin/sh
`which node || which nodejs` <<__HERE__
console.log('ok');
__HERE__

আপনি যা চান তাই করতে পারবেন না তাই পরিবর্তে আপনি যা করেন তা শেল স্ক্রিপ্ট চালানো হয়, তাই #!/bin/sh। যে শেল স্ক্রিপ্ট নোড চালানো প্রয়োজন ফাইলের পাথ পাবেন, যে হয় which node || which nodejs। ব্যাককোটগুলি এখানে রয়েছে যাতে এটি কার্যকর হয়, সুতরাং 'which node || which nodejs'(উদ্ধৃতিগুলির পরিবর্তে ব্যাককোটগুলি সহ) কেবল নোডকে কল করে। তারপরে, আপনি কেবল এটির সাথে আপনার স্ক্রিপ্টটি খাওয়ান <<__HERE__পুলিশের স্ক্রিপ্ট বিভেদক হয়। এবং এটি console.log('ok');স্ক্রিপ্টের একটি উদাহরণ যা আপনার স্ক্রিপ্টের সাথে প্রতিস্থাপন করা উচিত।


একটি ব্যাখ্যা ভাল হবে
0xC0000022L

বেটার এড়ানোর প্যারামিটার সম্প্রসারণ, কমান্ড প্রতিকল্পন এবং গাণিতিক সম্প্রসারণ করার জন্য এখানে নথি বিভেদক সঞ্চালনের আগে জাভাস্ক্রিপ্ট কোড সম্পাদন করা যায় উদ্ধৃতি: <<'__HERE__'
manatwork

এটি আকর্ষণীয় হয়ে উঠছে! যদিও //bin/falseআমার এমএসওয়াইএস পরিবেশে কাজ করে না, এবং আমার nodeবাসায় থাকায় আমার ব্যাকটিক্সের চারপাশে উদ্ধৃতিগুলি দরকার C:\Program Files\...। হ্যাঁ, আমি একটি ভয়াবহ পরিবেশে কাজ করি ...
ড্যানডাক

1
//bin/falseম্যাক ওএস এক্সেও কাজ করে না। আমি দুঃখিত, তবে এটি আর পোর্টেবল মনে হয় না।
নাচছে

2
whichকমান্ড এছাড়াও পোর্টেবল নয়।
jordanm

9

এটি কেবলমাত্র ডেবিয়ান-ভিত্তিক সিস্টেমগুলিতেই একটি সমস্যা, যেখানে নীতিটি অর্থে কাটিয়ে ওঠে।

ফেডোরা কখন নোডেজ নামে একটি বাইনারি সরবরাহ করেছিল তা আমি জানি না, তবে আমি এটি কখনই দেখিনি। প্যাকেজটিকে নোডেজ বলা হয় এবং এটি নোড নামে একটি বাইনারি ইনস্টল করে।

আপনার ডেবিয়ান-ভিত্তিক সিস্টেমে সাধারণ জ্ঞান প্রয়োগ করতে কেবল একটি সিমলিংক ব্যবহার করুন এবং তারপরে আপনি সান শেবাং ব্যবহার করতে পারেন। অন্য লোকেরা যেভাবেই বুদ্ধিমান শেবাংগুলি ব্যবহার করবে, সুতরাং আপনার সেই সিমিলিংকের প্রয়োজন হবে।

#!/usr/bin/env node

console.log("Spread the love.");

আমি দুঃখিত, তবে এটি প্রশ্নের উত্তর দেয় না। আমি রাজনৈতিক দৃষ্টিভঙ্গি বুঝতে পারি, তবে এখানে বিষয়টি এখানে নয়।
5:58

রেকর্ডের জন্য, কিছু ফেডোরা সিস্টেমে nodejsএক্সিকিউটেবল থাকে , তবে এটি ফেডোরার দোষ নয়। সত্যটি ভুল উপস্থাপনের জন্য দুঃখিত।
নাচছে

8
ক্ষমা চাইতে হবে না। আপনি বেশ ঠিক বলেছেন। আমার প্রতিক্রিয়া আপনার প্রশ্নের উত্তর দেয় না। এটি আপনার প্রশ্নের সাথে কথা বলে, প্রস্তাবিত যে প্রশ্নটি সুযোগের চেয়ে কম কার্যকর সমাধানগুলির মধ্যে সীমাবদ্ধ রাখবে। আমি ইতিহাস দ্বারা অবহিত ব্যবহারিক পরামর্শ দিচ্ছি। নোড এখানে নিজেকে খুঁজে পাওয়া প্রথম দোভাষী নয়। পার্ল শেবাং হওয়া উচিত বলে ঘোষণা করে যে লরি ওয়ালকে নিয়ে যাওয়ার পথে আপনি সেই গোলযোগ দেখেছিলেন #!/usr/bin/perl। এটি বলেছিল, আপনি আমার পরামর্শগুলি পছন্দ করতে বা প্রয়োগ করতে বাধ্য নন। শান্তি বর্ষিত হোক।
শেলডনহ

3

আপনি যদি একটি ছোট .shফাইল তৈরি করতে আপত্তি না করেন তবে আপনার জন্য আমি একটি সামান্য সমাধান সমাধান করব। কোন নোড ব্যবহারের জন্য নির্বাহযোগ্য তা নির্ধারণ করতে আপনি একটি ছোট শেল স্ক্রিপ্ট তৈরি করতে পারেন এবং আপনার শেবাংয়ে এই স্ক্রিপ্টটি ব্যবহার করতে পারেন:

shebang.sh :

#!/bin/sh
`which node || which nodejs` $@

স্ক্রিপ্ট.জেএস :

#!./shebang.sh
console.log('hello');

এক্সিকিউটেবল উভয়ই চিহ্নিত করুন, এবং চালান ./script.js

এইভাবে, আপনি বহুগ্লোট স্ক্রিপ্টিং এড়ান। আমি মনে করি না যে একাধিক শেবাং লাইন ব্যবহার করা সম্ভব, যদিও এটি একটি ভাল ধারণা বলে মনে হয়।

যদিও এটি আপনার চাইলে সমস্যাটি সমাধান করে তবে মনে হয় যে এটির জন্য কেউই পাত্তা দেয় না। উদাহরণস্বরূপ, uglifyjs এবং coffeescript ব্যবহার করে #!/usr/bin/env node, এনপিএম শেল স্ক্রিপ্টটিকে একটি এন্ট্রি পয়েন্ট হিসাবে ব্যবহার করে, যা আবার এক্সিকিউটেবলকে নামের সাথে স্পষ্টভাবে ডাকে node। আমি একজন উবুন্টু ব্যবহারকারী এবং আমি সর্বদা নোড সংকলন করায় এটি আমি জানতাম না। আমি এটি একটি বাগ হিসাবে রিপোর্ট করার জন্য বিবেচনা করছি।


আমি নিশ্চিত যে আপনাকে কমপক্ষে chmod +xশ স্ক্রিপ্টে ব্যবহারকারীকে জিজ্ঞাসা করতে হবে ... তাই আপনি তাদের নোডকে এক্সিকিউটেবলের জন্য লোকেশন দেওয়ার জন্য একটি ভেরিয়েবল সেট করতে বলবেন ...
xavierm02

@ xavierm02 স্ক্রিপ্টটি chmod +x'ডি' প্রকাশ করতে পারে । এবং আমি একমত যে একটি NODE ভেরিয়েবল এর চেয়ে ভাল which node || which nodejs। তবে অনেক বড় নোড প্রকল্প স্রেফ ব্যবহার করলেও অনুসন্ধানকারী একটি বাইরের বাইরে বাক্সের অভিজ্ঞতা সরবরাহ করতে চায় #!/usr/bin/env node

1

কেবলমাত্র সম্পূর্ণতার জন্য এখানে দ্বিতীয় লাইনটি করার কয়েকটি উপায় রয়েছে:

// 2>/dev/null || echo yes
false //|| echo yes

তবে বাছাই করা উত্তরের উপর কারওরই সুবিধা নেই:

':' //; || echo yes

এছাড়াও, যদি আপনি জানতেন যে উভয় nodeবা nodejs(তবে উভয়ই নয়) পাওয়া যাবে, তবে নিম্নলিখিত কাজগুলি:

exec `command -v node nodejs` "$0" "$@"

তবে এটি একটি বড় "যদি", তাই আমি মনে করি নির্বাচিত উত্তরটি সবচেয়ে ভাল।


অতিরিক্ত হিসাবে, আপনি foobar // 2>/dev/nullযতক্ষণ foobarনা কোনও আদেশ না দিয়ে চালাতে পারেন । এবং কোনও পসিক্স সিস্টেমে পাওয়া অনেকগুলি ইউটিলিটি// যুক্তি দিয়ে চালানো যেতে পারে ।
নাচছে

1

আমি বুঝতে পারি যে এটি প্রশ্নের উত্তর দেয় না, তবে আমি নিশ্চিত যে প্রশ্নটি একটি মিথ্যা ভিত্তিতে জিজ্ঞাসা করা হয়েছে।

উবুন্টু এখানে ভুল আছে। আপনার নিজস্ব স্ক্রিপ্টের জন্য একটি সর্বজনীন শেবাং লিখলে অন্যান্য প্যাকেজগুলির কোনও পরিবর্তন হবে না যার উপর আপনার কোনও নিয়ন্ত্রণ নেই যা ডি-ফ্যাক্টো স্ট্যান্ডার্ড ব্যবহার করে #!/usr/bin/env node। আপনার সিস্টেম আবশ্যক প্রদান nodeমধ্যে PATHযদি এটা লক্ষ্য করে nodejs এটিতে চালানোর জন্য কোনও স্ক্রিপ্টের জন্য শুভেচ্ছা।

উদাহরণস্বরূপ, এমনকি উবুন্টু-সরবরাহিত npmপ্যাকেজগুলি প্যাকেজগুলিতে শেবাংগুলিকে পুনরায় লেখায় না:

$ cd
$ rm -rf test_npm
$ mkdir test_npm
$ cd test_npm
$ npm install mkdirp 2>&1 | grep -ve home
`-- mkdirp@0.5.1
  `-- minimist@0.0.8

npm WARN test_npm No description
npm WARN test_npm No repository field.
npm WARN test_npm No README data
npm WARN test_npm No license field.
$ node_modules/.bin/mkdirp testdir
/usr/bin/env: 'node': No such file or directory
$ head -n1 node_modules/.bin/mkdirp
#!/usr/bin/env node
$ npm --version
3.5.2
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.