මගේ ෂෙබාං ලෙස “#! / Path / to / NAME” වෙනුවට “#! / Usr / bin / env NAME” භාවිතා කිරීම වඩා හොඳ ඇයි?


499

මම අනෙක් අයගෙන් ලබාගත් සමහර ස්ක්‍රිප්ට් වල ෂෙබාං #!/path/to/NAMEඇති අතර අනෙක් ඒවා (එකම මෙවලම භාවිතා කරමින්, නම) ෂෙබාං ඇති බව මම දනිමි #!/usr/bin/env NAME.

දෙකම නිසි ලෙස ක්රියා කරන බව පෙනේ. නිබන්ධන වල (උදාහරණයක් ලෙස පයිතන්හි), දෙවන ෂෙබාං වඩා හොඳ යැයි යෝජනාවක් ඇති බව පෙනේ. නමුත්, මෙය එසේ වන්නේ මන්දැයි මට හරියටම තේරෙන්නේ නැත.

පසුකාලීන ෂෙබාං භාවිතා කිරීම සඳහා, නම PATH හි තිබිය යුතු බවත්, පළමු ෂෙබාං හි මෙම සීමාව නොමැති බවත් මම තේරුම් ගතිමි.

එසේම, (මට පෙනේ) පළමුවැන්න වඩා හොඳ ෂෙබාං වනු ඇති බව පෙනේ, මන්ද එය හරියටම NAME පිහිටා ඇති ස්ථානය නියම කරයි. එබැවින්, මෙම අවස්ථාවේ දී, NAME හි බහු සංස්කරණ තිබේ නම් (උදා: / usr / bin / NAME, / usr / local / bin / NAME), පළමු අවස්ථාව භාවිතා කළ යුත්තේ කුමන ඒවාද යන්න නියම කරයි.

මගේ ප්‍රශ්නය වන්නේ පළමු ෂෙබාං දෙවන එකට වඩා කැමති ඇයි?



G TheGeeko61: මගේ නඩුවේදී මට යමක් කැඩී ගොස් ඇති අතර සමහර විචල්‍යයන් env හි නොමැත. එබැවින් env නිවැරදිව පටවා ඇත්දැයි තහවුරු කර ගැනීමට මෙම ෂෙබාං භාවිතා කිරීමට මම යෝජනා කරමි.
ගිගමෙග්ස්

Answers:


8

අරමුණු නිර්ණායක / අවශ්‍යතා:

ෂී-බැන්ග් එකක පරිවර්තකයෙකුට නිරපේක්ෂ හෝ තාර්කික ( /usr/bin/env) මාර්ගයක් භාවිතා කළ යුතුද යන්න තීරණය කිරීමේදී , (2) ප්‍රධාන කරුණු තිබේ:

අ) මේ භාෂා පරිවර්තක ඉලක්කය පද්ධතිය මත සොයා ගත හැකි

ආ) මෙම නිවැරදි අනුවාදය වන භාෂණ ඉලක්කය පද්ධතිය මත සොයා ගත හැකි

අපි නම් එකඟ "බව ආ) " ප්රිය වේ, අප එකඟ :

ඇ) වැරදි පරිවර්තක අනුවාදයක් භාවිතා කර ක්‍රියාත්මක කිරීමට වඩා නොගැලපෙන ප්‍රති .ල ලබා ගැනීමට වඩා අපගේ ස්ක්‍රිප්ට් අසමත් වීම වඩාත් සුදුසුය .

ආ) ” කාරණා ගැන අප එකඟ නොවන්නේ නම් , සොයාගත් ඕනෑම පරිවර්තකයෙකු ප්‍රමාණවත් වේ.

පරීක්ෂා කිරීම:

තාර්කික මාර්ගයක් භාවිතා කිරීම- ෂී-බැන්ග් /usr/bin/envහි පරිවර්තකයාට එකම විධානාවලිය එකම පරිවර්තකයාට විවිධ මාර්ග ඇති ඉලක්කගත ධාරකයන් මත සාර්ථකව ක්‍රියාත්මක කිරීමට ඉඩ සලසන වඩාත්ම විස්තීරණ විසඳුම වන බැවින්, අපි එය පරීක්ෂා කර බලමු- එහි ජනප්‍රියතාවය නිසා පයිතන් භාවිතා කරමින් - එය අපගේ නිර්ණායක සපුරාලන්නේ දැයි බැලීමට.

  1. ජනප්‍රිය (“ සෑම ” නොවේ) මෙහෙයුම් පද්ධතිවල /usr/bin/envපුරෝකථනය කළ හැකි, ස්ථාවර ස්ථානයක ජීවත් වේද ? ඔව් :

    • RHEL 7.5
    • උබුන්ටු 18.04
    • රාස්බියන් 10 ("බස්ටර්")
    • OSX 10.15.02
  2. පයිතන් ස්ක්‍රිප්ටයට පහළින් පරීක්ෂණ අතරතුර අථත්ය ලියුම් කවරවල ඇතුළත හා පිටත ( පයිපෙන්ව් භාවිතා කරන ලදි):

    #!/usr/bin/env pythonX.x import sys print(sys.version) print('Hello, world!')

  3. ස්ක්‍රිප්ටයේ ෂී-බැන්ග් ටොගල් කර ඇත්තේ අපේක්ෂිත පයිතන් අනුවාද අංකයෙනි (සියල්ල එකම ධාරකයේ ස්ථාපනය කර ඇත):

    • #! / usr / bin / env python2
    • #! / usr / bin / env python2.7
    • #! / usr / bin / env python3
    • #! / usr / bin / env python3.5
    • #! / usr / bin / env python3.6
    • #! / usr / bin / env python3.7
  4. අපේක්ෂිත ප්‍රති results ල: that print(sys.version)= env pythonX.x. සෑම ./test1.pyවාරයක්ම වෙනස් ස්ථාපිත පයිතන් අනුවාදයක් භාවිතයෙන් ක්‍රියාත්මක කරන ලද අතර, ෂී-බැන්ග් හි දක්වා ඇති නිවැරදි අනුවාදය මුද්‍රණය කරන ලදි.

  5. පරීක්ෂණ සටහන්:

    • පරීක්ෂණ තනිකරම පයිතන්ට පමණක් සීමා විය
    • පර්ල්: පයිතන් මෙන් - FHS අනුව ජීවත් විය යුතුය/usr/bin
    • හැකි සෑම ලිනක්සි / යුනික්සි මෙහෙයුම් පද්ධතියක් සහ එක් එක් මෙහෙයුම් පද්ධතියේ අනුවාදය මත හැකි සෑම සංයෝජනයක්ම මම උත්සාහ කර නැත.

නිගමනය:

#!/usr/bin/env pythonපරිශීලකයාගේ මාවතේ සොයාගත් පයිතන්ගේ පළමු අනුවාදය එය සත්‍යයක් වුවද , අපට අනුවාද අංකයක් සඳහන් කිරීමෙන් මෙම හැසිරීම නවීකරණය කළ හැකිය #!/usr/bin/env pythonX.x. ඇත්ත වශයෙන්ම, සංවර්ධකයින් කුමන පරිවර්තකය " පළමුව " සොයා ගන්නේද යන්න නොසලකයි, ඔවුන් සැලකිලිමත් වන්නේ ඔවුන්ගේ කේතය ක්‍රියාත්මක වන්නේ ඔවුන් දන්නා නිශ්චිත පරිවර්තකය භාවිතයෙන් ඔවුන්ගේ කේතයට අනුකූල වන බව ය . ..

අතේ ගෙන යාහැකි / නම්‍යශීලිත්වය අනුව, තාර්කික - /usr/bin/env- නිරපේක්ෂ මාවතකට වඩා අවශ්‍යතා සපුරාලීම පමණක් නොව, අ), ආ) සහ ඇ) පයිතන්හි විවිධ අනුවාදයන් සමඟ මගේ පරීක්ෂණයෙන් පමණක් නොව, එකම අනුවාදය සොයා ගැනීමේ නොපැහැදිලි-තර්කනයේ වාසිය ද ඇත. විවිධ මෙහෙයුම් පද්ධතිවල විවිධ මාර්ගවල ජීවත් වුවද පරිවර්තකය. බොහෝ ඩිස්ට්‍රෝවරු එෆ්එච්එස් වලට ගරු කළත් , සියල්ලෝම එසේ නොකරති .

ඒ නිසා තිර රචනය ඇත එහිදී FAIL විවිධ ද්විමය ජීවිත නම් නිරපේක්ෂ මාර්ගය නම් shebang හි නිශ්චිතව දක්වා, භාවිතා කරමින් එම තිර රචනය තාර්කික මාර්ගය සාර්ථක එය එමගින් වේදිකා පුරා වැඩි විශ්වසනීයත්වය සහ extensibility ඉදිරිපත්, තරගය සම්බ වන තුරු දමනව ලෙස.


3
විශිෂ්ට විශ්ලේෂණයක්. අපි එය අගය කරමු.
TheGeeko61

1
ප්‍රශ්නය පයිතන්ට විශේෂිත නොවේ. උදාහරණයක් ලෙස interpX සහ වෙනත් පරිවර්තකයන් ස්ථාපනය කරනු ඇතැයි ඔබට ආරක්ෂිතව උපකල්පනය කළ හැකි යැයි මම නොසිතමි interpX.x. උදාහරණයක් ලෙස, මේ මොහොත වන විට ද මම භාවිතා කරනවා පද්ධතියක් ඇත perl, perl5.26.3සහ perl5.30.1. තවත් ඇත perlහා perl5.26.1. දෙදෙනාම perl5අණක් නැත. තවද, ඔබ විසින් පරීක්ෂා කරන ලද ඕනෑම පද්ධතියක pythonXසහ pythonX.xපරිවර්තකයන් ස්ථාපනය කර ඇත්තේ කොතැනදැයි ඔබ සඳහන් කර නැත. ඔවුන් සියලු නම් /usr/binඉන් පසු ඔබේ අත්හදා කිසිම වාසියක් පෙන්නුම් කරන්නේ නැත #!/usr/bin/env pythonX.xපුරා #!/usr/bin/pythonX.x.
කීත් තොම්සන්

E කීත් තොම්සන් පයිතන් තෝරාගත්තේ එහි විශාල ජනප්‍රියත්වය නිසාය. අනෙක් පිළිතුරු සාමාන්‍ය ඒවා වූ අතර ප්‍රශ්නයට පිළිතුරු සැපයීම සඳහා වඩාත් ප්‍රායෝගික ප්‍රවේශයක් ගැනීමට මට අවශ්‍ය විය. පර්ල් සමඟ විශේෂයෙන් සම්බන්ධ වන පරිදි, "පරීක්ෂා කිරීම"> "සටහන්" හි මගේ යාවත්කාලීන පිළිතුරෙහි (ඔබගේ වලංගු ගැටළු වලට ප්‍රතිචාර දක්වමින්) සටහන් කරමි - මෙයද /usr/binFHS අනුව ජීවත් විය යුතුය . මගේ පිළිතුරෙන් එය ඇඟවුවද, විකල්ප දෙකම එකම
ප්‍රති result ලයක් ලබා දෙන ස්ථානවල

1
සෑම ලිනක්ස් පද්ධතියක්ම එෆ්එච්එස් වලට අනුකූල නොවන බව සලකන්න. තවද, "මුළු ලෝකයම ලිනක්ස් නොවේ" යන පැරණි කියමන අර්ථ නිරූපණය කරයි. බොහෝ යුනික්ස් (y) පද්ධති අනුමාන යටතේ, "විකල්ප, සහාය නොදක්වන තෙවන පාර්ශවයක් එකතු" ලෙස Python, perl බසට ලං පවා bash හෝ tcsh ඇති /usr/localහෝ /opt/*packagename*හෝ ඇත්තටම විදේශීය රැකියාවල.
වොන්බ්‍රෑන්ඩ්

498

එය වඩා හොඳ නොවේ.

මෙහි ඇති වාසිය #!/usr/bin/env pythonනම්, එය pythonපරිශීලකයාගේ පළමුව පෙනෙන ඕනෑම ක්‍රියාත්මක කළ හැකි දෙයක් භාවිතා කිරීමයි $PATH.

මෙම අවාසිය පිළිබඳ #!/usr/bin/env pythonඑය ඕනෑම දෙයක් භාවිත වේ pythonපළමු පරිශීලක දී ක්රියාත්මක දර්ශණය $PATH.

එයින් අදහස් කරන්නේ තිර රචනය ක්‍රියාත්මක කරන්නේ කවුරුන්ද යන්න මත පදනම්ව වෙනස් ලෙස හැසිරවිය හැකි බවයි. එක් පරිශීලකයෙකු සඳහා, එය /usr/bin/pythonමෙහෙයුම් පද්ධතිය සමඟ ස්ථාපනය කර ඇති දේ භාවිතා කරයි . තවත් කෙනෙකුට, එය /home/phred/bin/pythonනිවැරදිව ක්‍රියා නොකරන අත්හදා බැලීමක් භාවිතා කරයි .

නම් සහ pythonපමණක් ස්ථාපනය කර /usr/local/bin, නැති වූ පරිශීලක /usr/local/binදී $PATHපවා කේත රචනය ක්රියාත්මක කිරීමට නොහැකි වනු ඇත. (බොහෝ විට එය නවීන පද්ධතිවල එතරම් ඉඩක් නැත, නමුත් එය වඩාත් අපැහැදිලි පරිවර්තකයෙකුට පහසුවෙන් සිදුවිය හැකිය.)

විශේෂිත පද්ධතියක#!/usr/bin/python ස්ක්‍රිප්ට් ධාවනය කිරීමට භාවිතා කරන්නේ කුමන පරිවර්තකයද යන්න නිශ්චිතව සඳහන් කිරීමෙන් .

තවත් විභව ගැටළුවක් නම්, #!/usr/bin/envඋපක්‍රමය මඟින් ඔබට පරිවර්තකයාට තර්ක ඉදිරිපත් කිරීමට ඉඩ නොදීමයි (පිටපතේ නම හැර, එය ව්‍යංගයෙන් සම්මත වේ). මෙය සාමාන්‍යයෙන් ප්‍රශ්නයක් නොවේ, නමුත් එය විය හැකිය. බොහෝ පර්ල් ස්ක්‍රිප්ට් සමඟ ලියා ඇත #!/usr/bin/perl -w, නමුත් use warnings;මේ දිනවල නිර්දේශිත ප්‍රතිස්ථාපනය වේ. Csh ස්ක්‍රිප්ට් භාවිතා කළ යුතුය #!/bin/csh -f- නමුත් csh ස්ක්‍රිප්ට් මුලින් නිර්දේශ නොකරයි . නමුත් වෙනත් උදාහරණ තිබිය හැකිය.

මම නව පද්ධතියක ගිණුමක් ආරම්භ කරන විට ස්ථාපනය කරන පුද්ගලික ප්‍රභව පාලන පද්ධතියක පර්ල් ස්ක්‍රිප්ට් ගණනාවක් තිබේ. මම #!එක් එක් ස්ක්‍රිප්ටයේ රේඛාව මගේ ස්ථාපනය කරන විට එය වෙනස් කරන ස්ථාපක ස්ක්‍රිප්ට් එකක් භාවිතා කරමි $HOME/bin. (මට #!/usr/bin/perlමෑතකදී හැර වෙනත් කිසිවක් භාවිතා කිරීමට සිදු වී නැත ; එය පෙරල් බොහෝ විට පෙරනිමියෙන් ස්ථාපනය නොකළ කාලයට දිව යයි.)

සුළු කරුණක්: #!/usr/bin/envඋපක්‍රමය envවිධාන ලෙස විධානය අනිසි ලෙස භාවිතා කිරීමකි , එය මුලින් අදහස් කළේ (නමට අනුව) වෙනස් කළ පරිසරයක් සහිත විධානයක් ඉල්ලා සිටීමයි. තවද, සමහර පැරණි පද්ධතිවල (සන් ඕඑස් 4 ද ඇතුළුව, මා නිවැරදිව සිහිපත් කළහොත්) envවිධානය නොතිබුණි /usr/bin. මේ දෙකම සැලකිය යුතු කරුණක් විය නොහැක. envමේ ආකාරයෙන් ක්‍රියා කරයි, බොහෝ ස්ක්‍රිප්ට් #!/usr/bin/envඋපක්‍රමය භාවිතා කරයි , සහ මෙහෙයුම්කරුවන් එය බිඳ දැමීමට කිසිවක් නොකරනු ඇත. එය විය හැකි ඔබ ඔබේ තිර රචනය ඇත්තටම පැරණි පද්ධතිය මත ක්රියාත්මක කිරීමට අවශ්ය නම් ප්රශ්නයක්, නමුත්, පසුව, ඔබට එය කෙසේ හෝ වෙනස් කිරීමට අවශ්ය කිරීමට ඉඩ ඇති.

විය හැකි තවත් කාරණයක් නම්, (අදහස් දැක්වීමේදී එය පෙන්වා දීම ගැන සොපලාජෝ ඩි ඇරියරෙස්ට ස්තූතියි) ක්‍රෝන් රැකියා සීමිත පරිසරයක් සමඟ ක්‍රියාත්මක වීමයි. විශේෂයෙන්, $PATHසාමාන්‍යයෙන් එවැනි දෙයක් /usr/bin:/bin. එබැවින් පරිවර්තකය අඩංගු නාමාවලිය එම නාමාවලි වලින් එකක සිදු නොවන්නේ නම්, එය $PATHපරිශීලක කවචයක ඔබගේ පෙරනිමියෙන් වුවද, /usr/bin/envඋපක්‍රමය ක්‍රියා නොකරනු ඇත. ඔබට නිශ්චිත මාර්ගය නියම කළ හැකිය, නැතහොත් සැකසීමට ඔබේ හරස්කඩට රේඛාවක් එක් කළ හැකිය $PATH( man 5 crontabවිස්තර සඳහා).


5
/ Usr / bin / perl perl 5.8, OM HOME / bin / perl 5.12 නම්, සහ ෂෙබැන්ග්ස් හි 5.12 දෘ c කේත / usr / bin / perl අවශ්‍ය වන ස්ක්‍රිප්ට් එකක් නම්, එය ස්ක්‍රිප්ට් ධාවනය කිරීමට විශාල වේදනාවක් විය හැකිය. PATH වෙතින් / usr / bin / env perl උදුරා ගැනීම ගැටළුවක් බව මම කලාතුරකින් දැක ඇත්තෙමි, නමුත් එය බොහෝ විට ඉතා ප්‍රයෝජනවත් වේ. එය ක්‍රියාත්මක කිරීමේ හැක් වලට වඩා ලස්සනයි!
විලියම් පර්සෙල්

9
ඔබට විශේෂිත පරිවර්තක අනුවාදයක් භාවිතා කිරීමට අවශ්‍ය නම්, / usr / bin / env තවමත් වඩා හොඳ බව සඳහන් කිරීම වටී. සාමාන්යයෙන් එහි හුදෙක් වේ බහු භාෂා පරිවර්තක සංස්කරණ perl5, perl5.12, perl5.10, python3.3, python3.32 නම් ඔබේ පරිගණකයේ ස්ථාපනය කර, ආදිය ඔබේ යෙදුම නිශ්චිත අනුවාදය පමණක් පරීක්ෂා කර ඇති නම්, ඔබ තවමත් නියම කල හැක, #! / usr / bin / env perl5.12 සහ පරිශීලකයා එය අසාමාන්‍ය තැනක ස්ථාපනය කර තිබුණත් කමක් නැත. මගේ අත්දැකීම් අනුව, 'පයිතන්' සාමාන්‍යයෙන් පද්ධති සම්මත අනුවාදයට සමමුහුර්ත කිරීමකි (අවශ්‍යයෙන්ම පද්ධතියේ නවතම අනුවාදය නොවේ).
root

7
@root: perl බසට ලං සඳහා, use v5.12;සේවය සමහර එම අරමුණ. හා #!/usr/bin/env perl5.12පද්ධතිය perl බසට ලං 5.14 නමුත් 5.12 තිබේ නම් අසාර්ථක වනු ඇත. පයිතන් 2 එදිරිව 3 සඳහා, #!/usr/bin/python2සහ #!/usr/bin/python3වැඩ කිරීමට ඉඩ ඇත.
කීත් තොම්සන්

3
Ood ගුඩ්පර්සන්: මම ස්ථාපනය කිරීමට පර්ල් පිටපතක් ලියමි යැයි සිතමු /usr/local/bin. එය නිවැරදිව ක්‍රියාත්මක වන බව මම දැන ගතිමි /usr/bin/perl. සමහර අහඹු පරිශීලකයෙකුට ඔහුගේ හෝ ඇය තුළ සිදුවිය හැකි ඕනෑම ක්‍රියාකාරීත්වයක් සමඟ එය ක්‍රියාත්මක වේදැයි මට අදහසක් නැත . සමහර විට කවුරුහරි පර්ල්හි පැරණි අනුවාදයක් අත්හදා බලමින් සිටී; මා විසින් නියම කර ඇති නිසා , මගේ ස්ක්‍රිප්ට් එක (පරිශීලකයා අනිවාර්යයෙන්ම නොදැන හෝ සැලකිලිමත් වන්නේ පර්ල් පිටපතක්) වැඩ කිරීම නවත්වන්නේ නැත. perl$PATH#!/usr/bin/perl
කීත් තොම්සන්

5
එය සමඟ වැඩ නොකරන්නේ නම් /usr/bin/perl, මම ඉතා ඉක්මණින් සොයා ගන්නෙමි, එය යාවත්කාලීනව තබා ගැනීම පද්ධති හිමිකරුගේ / පරිපාලකයාගේ වගකීම වේ. ඔබට මගේ පිටපත ඔබේම පර්ල් එකකින් ධාවනය කිරීමට අවශ්‍ය නම්, පිටපතක් අල්ලාගෙන වෙනස් කිරීමට හෝ එය හරහා ආයාචනා කිරීමට නිදහස් වන්න perl foo. (මෙම පිළිතුර ඉහළට ඔසවා තැබූ පුද්ගලයින් 55 දෙනා ද යමක් හෝ දෙකක් දන්නා බව ඔබ සලකා බැලිය හැකිය. නිසැකවම ඔබ නිවැරදියි, ඔවුන් සියල්ලන්ම වැරදියි, නමුත් මම ඔට්ටු අල්ලන ක්‍රමය එය නොවේ.)
කීත් තොම්සන්

105

/ Usr / bin / env මඟින් ඔබේ අර්ථ නිරූපණය කළ හැකි $PATHඅතර එමඟින් ස්ක්‍රිප්ට් වඩාත් අතේ ගෙන යා හැකිය.

#!/usr/local/bin/python

ඔබගේ ස්ක්‍රිප්ට් ක්‍රියාත්මක වන්නේ පයිතන් / usr / local / bin තුළ ස්ථාපනය කර ඇත්නම් පමණි.

#!/usr/bin/env python

ඔබේ අර්ථ නිරූපණය කර ඔබගේ $PATHඕනෑම නාමාවලියක පයිතන් සොයා ගනු ඇත $PATH.

ඔබේ තිර රචනය වැඩි අතේ ගෙන යා හැකි වන අතර, මෙම පිඹුරා ලෙස ස්ථාපනය වන පද්ධති මත වෙනස් කිරීමකින් තොරව කටයුතු කරනු ඇත ඒ නිසා /usr/bin/python, හෝ /usr/local/bin/python, හෝ අභිරුචි බහලුම් (එකතු කර ඇති බව $PATH), වැනි /opt/local/bin/python.

envදෘඩ කේත කරන ලද මාර්ග වලට වඩා කැමති වන්නේ අතේ ගෙන යා හැකි එකම හේතුවයි .


20
භාවිතය වැඩි වන විට pythonක්‍රියාත්මක කළ හැකි අය සඳහා වන අභිරුචි නාමාවලි විශේෂයෙන් පොදු virtualenvවේ.
මොනිකා සෙලියෝ සඳහා එස්ඊ වර්ජනය කිරීම

1
මොකද කරන්නේ #! python , එය භාවිතා නොකරන්නේ ඇයි?
ක්‍රිස්ටියන්ප්

6
#! pythonඔබ භාවිතා කරන්නේ පයිතන් ද්විමය හා සමාන නාමාවලියක තිබිය යුතු නිසාය, මන්ද යත්, මුරපදය pythonගොනුව වෙත සම්පූර්ණ මාර්ගය ලෙස අර්ථකථනය කර ඇති බැවිනි. වත්මන් නාමාවලියෙහි ඔබට පයිතන් ද්විමය නොමැති නම්, ඔබට වැනි දෝෂයක් ලැබෙනු ඇත bash: ./script.py: python: bad interpreter: No such file or directory. එය ඔබ භාවිතා කළ ආකාරයටම වේ#! /not/a/real/path/python
ටිම් කෙනඩි

50

දී ඇති පද්ධතියක නිරපේක්ෂ මාර්ගය නියම කිරීම වඩාත් නිවැරදි ය. අවාසිය නම් එය ඉතා නිවැරදි වීමයි. පර්ල් හි පද්ධති ස්ථාපනය ඔබගේ ස්ක්‍රිප්ට් සඳහා පැරණි බව ඔබට වැටහී ඇති අතර ඒ වෙනුවට ඔබේම දෑ භාවිතා කිරීමට ඔබට අවශ්‍ය යැයි සිතමු: එවිට ඔබට ස්ක්‍රිප්ට් සංස්කරණය කර වෙනස් කළ #!/usr/bin/perlයුතුය #!/home/myname/bin/perl. නරකම දෙය නම්, ඔබට /usr/binසමහර යන්ත්‍රවල, වෙනත් යන්ත්‍රවල /usr/local/binසහ /home/myname/bin/perlවෙනත් යන්ත්‍රවල පර්ල් තිබේ නම්, ඔබට ස්ක්‍රිප්ට් වල වෙනම පිටපත් තුනක් පවත්වා ගෙන ගොස් සෑම යන්ත්‍රයකම සුදුසු එකක් ක්‍රියාත්මක කිරීමට සිදුවනු ඇත.

#!/usr/bin/envPATHනරක නම් කැඩී යයි , නමුත් ඕනෑම දෙයක් පාහේ කරයි. නරක සමඟ ක්‍රියා කිරීමට උත්සාහ කිරීම PATHඉතා කලාතුරකින් ප්‍රයෝජනවත් වන අතර, ස්ක්‍රිප්ට් ක්‍රියාත්මක වන පද්ධතිය ගැන ඔබ දන්නේ අල්ප වශයෙනි, එබැවින් ඔබට කෙසේ හෝ නිරපේක්ෂ මාර්ගයක් මත විශ්වාසය තැබිය නොහැක.

සෑම යුනික්ස් ප්‍රභේදයක්ම පාහේ ඔබට විශ්වාසය තැබිය හැකි වැඩසටහන් දෙකක් තිබේ: /bin/sh සහ /usr/bin/env. සමහර අපැහැදිලි සහ බොහෝ දුරට විශ්‍රාම ගිය යුනික්ස් ප්‍රභේදයන් /bin/envනොමැතිව /usr/bin/envතිබුනද ඔබට ඒවා හමුවීමට හැකියාවක් නැත. නවීන පද්ධති /usr/bin/envහරියටම ඇත්තේ ෂෙබාං වල බහුලව භාවිතා වන බැවිනි. /usr/bin/envඔබට විශ්වාස කළ හැකි දෙයක්.

ඊට අමතරව /bin/sh, ඔබ ෂෙබාං හි නිරපේක්ෂ මාර්ගයක් භාවිතා කළ යුතු එකම අවස්ථාව වන්නේ ඔබේ ස්ක්‍රිප්ට් අතේ ගෙන යා හැකි යැයි අදහස් නොකිරීමයි, එබැවින් ඔබට පරිවර්තකයා සඳහා දන්නා ස්ථානයක් විශ්වාස කළ හැකිය. උදාහරණයක් ලෙස, ලිනක්ස් මත පමණක් ක්‍රියාත්මක වන bash ස්ක්‍රිප්ටයක් ආරක්ෂිතව භාවිතා කළ හැකිය #!/bin/bash. ගෘහස්ථව පමණක් භාවිතා කිරීමට අදහස් කරන ස්ක්‍රිප්ටයකට නිවාස පරිවර්තක ස්ථාන සම්මුතීන් මත විශ්වාසය තැබිය හැකිය.

#!/usr/bin/envඅවාසි ඇත. එය නිරපේක්ෂ මාර්ගයක් නියම කිරීමට වඩා නම්‍යශීලී නමුත් තවමත් පරිවර්තක නාමය දැන ගැනීම අවශ්‍ය වේ. ඉඳහිට ඔබට නොමැති පරිවර්තකයෙකු ධාවනය කිරීමට අවශ්‍ය විය හැකිය $PATH, උදාහරණයක් ලෙස ස්ක්‍රිප්ටයට සාපේක්ෂව ස්ථානයක. එවැනි අවස්ථාවන්හිදී, ඔබට බොහෝ විට සම්මත කවචය සහ ඔබ අපේක්ෂිත පරිවර්තකයා විසින් අර්ථ නිරූපණය කළ හැකි බහු භාෂා පිටපතක් සෑදිය හැකිය. උදාහරණයක් ලෙස, පයිතන් 2 ස්ක්‍රිප්ටය අතේ ගෙන යා හැකි pythonපයිතන් 3 සහ python2පයිතන් 2 පද්ධති pythonසහ පයිතන් 2 පවතින හා python2නොපවතින පද්ධති සඳහා :

#!/bin/sh
''':'
if type python2 >/dev/null 2>/dev/null; then
  exec python2 "$0" "$@"
else
  exec python "$0" "$@"
fi
'''
# real Python script starts here
def …

24

විශේෂයෙන් perl සඳහා, භාවිතා #!/usr/bin/envකිරීම හේතු දෙකක් නිසා නරක අදහසකි.

පළමුව, එය අතේ ගෙන යා නොහැකි ය. සමහර අපැහැදිලි වේදිකාවල env / usr / bin හි නොමැත. දෙවනුව, කීත් තොම්සන් සඳහන් කළ පරිදි, එය ෂෙබාං රේඛාව මත තර්ක ඉදිරිපත් කිරීමේදී කරදර ඇති කළ හැකිය. උපරිම අතේ ගෙන යා හැකි විසඳුම මෙයයි:

#!/bin/sh
exec perl -x "$0" "$@"
#!perl

එය ක්‍රියාත්මක වන ආකාරය පිළිබඳ විස්තර සඳහා, 'perldoc perlrun' සහ -x තර්කය ගැන එය පවසන දේ බලන්න.


1
හරියටම මා සොයමින් සිටි පිළිතුර: පර්ල් ස්ක්‍රිප්ට් සඳහා “ෂෙබාං” ලිවිය හැකි ආකාරය, එමඟින් අමතර ආයුධ පර්ල් වෙත යැවීමට ඉඩ සලසයි (ඔබේ උදාහරණයේ අවසාන පේළිය අතිරේක ආයුධ පිළිගනී).
අමොක් හුගින්සන්

M අමොක්හුගින්සන් එය බොඳ වූ ක්ලඩ්ජ් ය.
වොන්බ්‍රෑන්ඩ්

එය එසේ ය, නමුත් එය ක්‍රියා විරහිත ක්ලඩ්ජ් ය . අඩු ක්ලඩ්ජි විසඳුම් ක්‍රියා නොකරන නිසා එය පවතින්නේ අවුල් සහගත ක්ලඩ්ජ් ය.
ආචාර්ය හයිඩ්

17

මේ දෙක අතර වෙනසක් ඇතිවීමට හේතුව ස්ක්‍රිප්ට් ක්‍රියාත්මක වන ආකාරයයි.

භාවිතා කිරීම /usr/bin/env(වෙනත් පිළිතුරු වල සඳහන් පරිදි /usr/binසමහර මෙහෙයුම් පද්ධතිවල නොමැත) ඔබට අවශ්‍ය වන්නේ ක්‍රියාත්මක කළ හැකි නමක් පසුව තැබිය නොහැකි නිසාය #!- එය නිරපේක්ෂ මාර්ගයක් විය යුතුය. මෙයට හේතුව #!යාන්ත්‍රණය කවචයට වඩා පහත් මට්ටමක ක්‍රියාත්මක වීමයි. එය කර්නලයේ ද්විමය පැටවුමේ කොටසකි. මෙය පරීක්ෂා කළ හැකිය. මෙය ගොනුවකට දමා එය ක්‍රියාත්මක කළ හැකි ලෙස සලකුණු කරන්න:

#!bash

echo 'foo'

ඔබ එය ක්‍රියාත්මක කිරීමට උත්සාහ කරන විට එය මෙවැනි දෝෂයක් මුද්‍රණය කරන බව ඔබට පෙනී යනු ඇත:

Failed to execute process './test.sh'. Reason:
The file './test.sh' does not exist or could not be executed.

ගොනුවක් ක්‍රියාත්මක කළ හැකි යැයි සලකුණු කර a සමඟ ආරම්භ වුවහොත් #!, කර්නලය (එය නොදන්නා $PATHහෝ වර්තමාන නාමාවලිය: මේවා පරිශීලක-ඉඩම් සංකල්ප වේ) නිරපේක්ෂ මාර්ගයක් භාවිතා කරමින් ගොනුවක් සොයනු ඇත. නිරපේක්ෂ මාර්ගයක් භාවිතා කිරීම ගැටළු සහගත බැවින් (වෙනත් පිළිතුරු වල සඳහන් පරිදි), යමෙකු උපක්‍රමයක් ඉදිරිපත් කළේය: ඔබට යමක් ධාවනය කිරීමට /usr/bin/env(එය සෑම විටම පාහේ එම ස්ථානයේ ඇත) ධාවනය කළ හැකිය $PATH.


12

භාවිතා කිරීමේදී තවත් ගැටළු දෙකක් තිබේ #!/usr/bin/env

  1. එය පරිවර්තකයාට සම්පූර්ණ මාර්ගය නියම කිරීමේ ගැටළුව විසඳන්නේ නැත, එය එය වෙත ගෙන යයි env.

    envඇතුළත හෝ පයිතන් බවට සහතික වී ඇති /usr/bin/envප්‍රමාණයට වඩා වැඩි bashවීම සහතික නොවේ ./bin/bash/usr/bin/python

  2. env ARGV [0] පරිවර්ථකයාගේ නම සමඟ නැවත ලියයි (e..g bash හෝ python).

    මෙය ඔබගේ ස්ක්‍රිප්ටයේ නම දර්ශනය වීම වළක්වයි, උදා: psප්‍රතිදානය (හෝ එය දිස්වන ආකාරය / කොතැනද යන්න වෙනස් කරයි) සහ එය සොයා ගැනීමට නොහැකි වේ, උදා.ps -C scriptname.sh

[යාවත්කාලීන කිරීම 2016-06-04]

තුන්වන ගැටළුව:

  1. ඔබේ PATH වෙනස් කිරීම ස්ක්‍රිප්ට් එකක පළමු පේළිය සංස්කරණය කරනවාට වඩා වැඩකි, විශේෂයෙන් එවැනි සංස්කරණ ස්ක්‍රිප්ට් කිරීම සුළුපටු නොවේ. උදා:

    printf "%s\n" 1 i '#!'$(type -P python2) . w | ed foo.py

    $ PATH වෙත ඩිරෙක්ටරියක් එකතු කිරීම හෝ කල් තබා ගැනීම තරමක් පහසුය (ගොනුවක් ස්ථිර කිරීම සඳහා ඔබට තවමත් සංස්කරණය කළ යුතුව ඇතත් - ඔබේ ~/.profileහෝ වෙනත් දෙයක් - නමුත් එය ස්ක්‍රිප්ට් කිරීම පහසු නැත. එය සංස්කරණය කිරීම පහසු නැත. , පළමු පේළියේ නොවේ).

    PATH නාමාවලි වල අනුපිළිවෙල වෙනස් කිරීම සැලකිය යුතු ලෙස වඩා දුෂ්කර ය .... සහ #!පේළිය සංස්කරණය කිරීමට වඩා දුෂ්කර ය .

    භාවිතා #!/usr/bin/envකිරීමෙන් ඔබට ලබා දෙන අනෙක් සියලුම ගැටලු ඔබට තවමත් ඇත .

    #!/usr/bin/envස්ක්‍රිප්ට් බහුවිධ පරිවර්තක අනුවාදයන් සමඟ පරීක්ෂා කිරීම සඳහා ප්‍රයෝජනවත් වන විවරණයකින් ll ජල්ලියාග්‍රේ යෝජනා කරන්නේ , “ඔවුන්ගේ PATH / PATH අනුපිළිවෙල වෙනස් කිරීමෙන් පමණි”

    ඔබට එය කිරීමට අවශ්‍ය නම්, #!ඔබේ ස්ක්‍රිප්ටයේ ඉහළින් පේළි කිහිපයක් තිබීම වඩා පහසුය (ඒවා ඕනෑම තැනක අදහස් දැක්වීමක් මිස මුල් පේළියකි) සහ ඔබට දැන් භාවිතා කිරීමට අවශ්‍ය එක කපා / පිටපත් කර අලවන්න. පළමු පේළිය.

    තුළ vi, එය කර්සරය #!ඔබට අවශ්‍ය රේඛාවට ගෙනයාම, පසුව ටයිප් කිරීම dd1GPහෝ Y1GP. සංස්කාරකයක් තරම් සුළු දෙයක් වුවද nano, පිටපත් කිරීමට හා ඇලවීමට මූසිකය භාවිතා කිරීමට තත්පර කිහිපයක් ගතවනු ඇත.


සමස්තයක් වශයෙන්, භාවිතා කිරීමේ වාසි #!/usr/bin/envඅවම වශයෙන් අවම වන අතර නිසැකවම අවාසි ඉක්මවා යාමට ආසන්න නොවන්න. "පහසුව" වාසිය පවා බොහෝ දුරට මායාවකි.

IMO, එය මෙහෙයුම් පද්ධති සමඟ වැඩ කළ යුතු දෙයක් නොවන බව සිතන විශේෂිත ක්‍රමලේඛකයෙකු විසින් ප්‍රවර්ධනය කරන ලද මෝඩ අදහසකි, ඒවා වටා වැඩ කළ යුතු ගැටළුවක් (හෝ නොසලකා හරිනු ලැබේ).

PS: එකවර විවිධ ගොනු වල පරිවර්තකය වෙනස් කිරීමට සරල පිටපතක් මෙන්න.

change-shebang.sh:

#!/bin/bash

interpreter="$1"
shift

if [ -z "$(type -P $interpreter)" ] ; then
  echo "Error: '$interpreter' is not executable." >&2
  exit 1
fi

if [ ! -d "$interpreter" ] && [ -x "$interpreter" ] ; then
  shebang='#!'"$(realpath -e $interpreter)" || exit 1
else
  shebang='#!'"$(type -P $interpreter)"
fi

for f in "$@" ; do
  printf "%s\n" 1 i "$shebang" . w | ed "$f"
done

එය උදා, change-shebang.sh python2.7 *.pyහෝ ලෙස ක්‍රියාත්මක කරන්නchange-shebang.sh $HOME/bin/my-experimental-ruby *.rb


4
මෙහි වෙනත් කිසිවෙකු ARGV [0] ගැටලුව සඳහන් කර නැත. තවද / / path / to / env නිකුතුව කිසිවෙකු එය භාවිතා කිරීම සඳහා වන එක් තර්කයක් සෘජුවම ආමන්ත්‍රණය කරන ස්වරූපයෙන් සඳහන් කර නැත (එනම්, බැෂ් හෝ පර්ල් අනපේක්ෂිත ස්ථානයක විය හැකිය).
cas

2
පරිවර්තක මාර්ග ගැටළුව සිම්ලින්ක් සහිත සිසැඩ්මින් විසින් හෝ ඔවුන්ගේ ස්ක්‍රිප්ට් සංස්කරණය කරන පරිශීලකයා විසින් පහසුවෙන් විසඳනු ලැබේ. මෙහි සඳහන් කර ඇති ෂෙබාං රේඛාව සහ වෙනත් ප්‍රශ්න සඳහා env භාවිතා කිරීම නිසා ඇති වන අනෙකුත් සියලු ගැටලු සමඟ කටයුතු කිරීමට ජනතාව දිරිමත් කිරීම සඳහා සැලකිය යුතු තරම් ගැටළුවක් නොවේ. එය cshස්ක්‍රිප්ටින් දිරිගැන්වීම නරක විසඳුමක් ප්‍රවර්ධනය කරන ආකාරයටම නරක විසඳුමක් ප්‍රවර්ධනය කරයි: එය ක්‍රියා කරන නමුත් වඩා හොඳ විකල්ප තිබේ.
cas

3
සයිසැඩ්මින් නොවන අයට එය කිරීමට ඔවුන්ගේ සිසැඩ්මින්ගෙන් ඉල්ලා සිටිය හැකිය. නැතහොත් ඔවුන්ට සරලවම පිටපත සංස්කරණය කර #!රේඛාව වෙනස් කළ හැකිය.
cas

3
මග හැරීමට env උදව් කරන්නේ එයයි: පයිතන් හෝ වෙනත් ඕනෑම දෙයකට සම්බන්ධ නැති sysadmin හෝ OS විශේෂිත තාක්ෂණික දැනුම මත පදනම්ව.
jlliagre

2
මම එය ඇත්තටම විශාල පිළිතුර වන නිසා මම, මෙම දහස් වරක් upvote පුළුවන් නම් කවර ක්රමයක් - කෙනෙකු භාවිතා කරයි නම් /usr/bin/envමම එක්කෝ කොබැඳි නැත්නම් ස්ථානීකව නොපවතියි එය ඉවත් කිරීමට අවශ්ය, හෝ ඔවුන් එය භාවිතා කළේ නැහැ මම ඒ එක් කිරීමට අවශ්ය නම්. අවස්ථා දෙකම සිදුවිය හැකි අතර, එබැවින් මෙම පිළිතුරෙහි දක්වා ඇති ස්ක්‍රිප්ට් මෙවලම් පෙට්ටියේ තිබිය හැකි ප්‍රයෝජනවත් මෙවලමකි.
jstine

10

මෙහි තවත් උදාහරණයක් එකතු කිරීම:

උදාහරණයක් ලෙස envබහුවිධ rvmපරිසරයන් අතර ස්ක්‍රිප්ට් බෙදා ගැනීමට ඔබට අවශ්‍ය විටදී භාවිතා කිරීමද ප්‍රයෝජනවත් වේ .

මෙය cmd රේඛාව මත ධාවනය #!/usr/bin/env rubyකිරීමෙන්, ස්ක්‍රිප්ටයක් තුළ භාවිතා කරන විට කුමන රූබි අනුවාදය භාවිතා වේදැයි පෙන්වයි :

env ruby --version

එමනිසා, ඔබ භාවිතා කරන විට env, ඔබේ ස්ක්‍රිප්ට් වෙනස් නොකර rvm හරහා විවිධ රූබි අනුවාද භාවිතා කළ හැකිය.


1
//, විශිෂ්ට අදහස. බහුවිධ පරිවර්තකයන්ගේ සමස්ත ලක්ෂ්‍යය කේතය බිඳ දැමීම හෝ කේතය එම නිශ්චිත පරිවර්තකයා මත රඳා නොපවතී .
නේතන් බසානිස්

6

ඔබ තනිකරම ලියන්නේ ඔබ හෝ ඔබේ රැකියාව සහ ඔබ අමතන පරිවර්තකයා සිටින ස්ථානය සැමවිටම එකම ස්ථානයක නම්, සෑම අතින්ම සෘජු මාර්ගය භාවිතා කරන්න. අනෙක් සියලුම අවස්ථාවල භාවිතා කරන්න #!/usr/bin/env.

මෙන්න හේතුව: ඔබේ තත්වය තුළ pythonඔබ භාවිතා කළ සින්ටැක්ස් නොසලකා පරිවර්තකයා එකම ස්ථානයක සිටියද බොහෝ දෙනෙකුට එය වෙනත් ස්ථානයක ස්ථාපනය කළ හැකිව තිබුණි. බොහෝ ප්‍රධාන ක්‍රමලේඛන පරිවර්තකයන් /usr/bin/නව මෘදුකාංග රාශියක පිහිටා ඇතත් එය පෙරනිමිය /usr/local/bin/.

#!/usr/bin/envඑකම පරිවර්තකයේ බහු සංස්කරණ ස්ථාපනය කර ඇති අතර ඔබේ කවචය පෙරනිමිය යුත්තේ කුමක් දැයි ඔබ නොදන්නේ නම්, සෑම විටම භාවිතා කිරීමට මම තර්ක කරමි .


6
"අනෙක් සෑම අවස්ථාවකම #! / Usr / bin / env භාවිතා කිරීම" ඉතා ශක්තිමත්. E කීත් තොම්සන් සහ වෙනත් අය පෙන්වා දෙන පරිදි, #! / Usr / bin / env යන්නෙන් අදහස් කරන්නේ පිටපත වෙනස් වන්නේ කවුරුන් / කෙසේද යන්න මත පදනම්ව වෙනස් ලෙස හැසිරවිය හැකි බවයි. සමහර විට මෙම වෙනස් හැසිරීම ආරක්ෂක දෝෂයක් විය හැකිය. // නිදසුනක් ලෙස, සෙටූයිඩ් හෝ සෙට්ජිඩ් ස්ක්‍රිප්ට් එකක් සඳහා "#! Setuid / gid ස්ක්‍රිප්ට් යනු කවදා හෝ හොඳ අදහසක්ද යන්න වෙනස් ගැටළුවක් - නමුත් නිසැකවම, සෙටූයිඩ් / ගිඩ් ක්‍රියාත්මක කළ හැකි කිසි විටෙකත් පරිශීලකයා සපයන පරිසරය විශ්වාස නොකළ යුතුය.
Krazy Glew

RaKrazyGlew, ඔබට ලිනක්ස් හි ස්ක්‍රිප්ටයක් සැකසිය නොහැක. ඔබ එය ක්‍රියාත්මක කළ හැකි ය. මෙම ක්‍රියාත්මක කළ හැකි දේ ලියන විට පරිසර විචල්‍යයන් ඉවත් කිරීම හොඳ පුරුද්දකි. සමහර පරිසර විචල්‍යයන් ද හිතාමතාම නොසලකා හරිනු ලැබේ.
මයියුල්

4

අතේ ගෙන යා හැකි සහ අනුකූලතා හේතූන් මත භාවිතා කිරීම වඩා හොඳය

#!/usr/bin/env bash

වෙනුවට

#!/usr/bin/bash

ලිනක්ස් / යුනික්ස් පද්ධතියක් මත ද්විමය ස්ථානයක් තිබිය හැකි බහු හැකියාවන් ඇත. ගොනු පද්ධති ධූරාවලිය පිළිබඳ සවිස්තරාත්මක විස්තරයක් සඳහා හයර් (7) මෑන්පේජ් පරීක්ෂා කරන්න.

FreeBSD උදාහරණයක් ලෙස මූලික පද්ධතියේ කොටසක් නොවන සියලුම මෘදුකාංග / usr / local / හි ස්ථාපනය කරයි . Bash මූලික පද්ධතියේ කොටසක් නොවන බැවින්, bash ද්විමය / usr / local / bin / bash හි ස්ථාපනය කර ඇත .

බොහෝ ලිනක්ස් බෙදාහැරීම් සහ ෆ්‍රීබීඑස්ඩී යටතේ ක්‍රියාත්මක වන අතේ ගෙන යා හැකි බාෂ් / සීඑස් / පර්ල් / ඕනෑම ස්ක්‍රිප්ටයක් ඔබට අවශ්‍ය විට, ඔබ #! / Usr / bin / env භාවිතා කළ යුතුය .

බොහෝ ලිනක්ස් ස්ථාපනයන් එන්වී ද්විමය / බින් / එන්වී හෝ සොෆ්ට්ලින්ක් / යූඑස්ආර් / බින් / බින් සමඟ සම්බන්ධ කර ඇති අතර ඒවා ෂෙබාං හි භාවිතා නොකළ යුතුය. එබැවින් #! / Bin / env භාවිතා නොකරන්න .


අක්ෂර වින්‍යාසය සඳහා, "මුළු ලෝකයම ලිනක්ස් නොවේ". සියලුම ලිනක්ස් පද්ධති හයර් (7) ට අනුකූල නොවේ. බොහෝ ලිනක්ස් නොවන පද්ධති වලට බාෂ් නැත, නැතහොත් එය අපැහැදිලි තැනක වළලනු ලබන “සහාය නොදක්වන, නිල නොවන ඇඩෝන” වේ.
වොන්බ්‍රෑන්ඩ්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.