/ usr / bin / env: php: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว


9

ฉันต้องการใช้สคริปต์. sh สำหรับการปรับใช้แอพของฉัน สคริปต์นั้นอยู่บนเซิร์ฟเวอร์ในบ้านของฉัน (เซิร์ฟเวอร์ Ubuntu 15.10) ทำเครื่องหมายว่าสามารถใช้งานได้ การเข้าถึงสคริปต์นี้ทำได้ผ่าน ssh โดยใช้บทช่วยสอนนี้ฉันได้ตั้งค่าการเข้าสู่ระบบ ssh ที่ใช้งานสคริปต์นั้น โดยพื้นฐานแล้วฉันเพิ่งเรียกssh deployer@XXX.com someArgumentsมันและมันรันสคริปต์ด้วยsomeArgumentsพารามิเตอร์ ผู้ใช้deployerมี uid = 0 ดังนั้นโดยพื้นฐานแล้วroot(จะมีการเปลี่ยนแปลงในอนาคตฉันได้ตั้งค่าไว้เพื่อกำจัดปัญหาสิทธิ์อนุญาตจนกว่าจะทำงานได้ดี)

และนี่คือสิ่งที่หากิน สคริปต์รายงาน/usr/bin/env: php: No such file or directoryที่คำสั่ง/bin/composer install(ใช้Composer ) สิ่งต่าง ๆ แปลก ๆ ยิ่งฉันดูบทนั้นมากขึ้น ก่อนบรรทัดนี้จะมีการเรียก/bin/composer self-updateและ/bin/composer -Vซึ่งทั้งคู่ทำงานอย่างถูกต้องและแสดงเอาต์พุตที่ถูกต้อง

ฉันได้ตรวจสอบสิ่งต่าง ๆ ต่อไปนี้:

  • /usr/bin/env php -vแสดงเวอร์ชั่น PHP ที่ถูกต้อง (เช่นเดียวกับ/usr/bin/php -v)
  • whereis php แสดง php: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
  • php5-cli ติดตั้งแพคเกจและเวอร์ชั่นใหม่ล่าสุดแล้ว
  • $PATH มี /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
  • which env แสดง /usr/bin/env

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว:

  • เรียกใช้สคริปต์โดยตรงbash deploy.shภายใต้รูท (เนื่องจากเป็นเช่นเดียวกับผู้ใช้) - ทำงานได้อย่างสมบูรณ์แบบโดยไม่มีข้อผิดพลาด
  • ใช้คำสั่งที่ล้มเหลวโดยตรง - ยังสมบูรณ์แบบโดยไม่มีข้อผิดพลาด

ดังนั้นนี่เป็นกรณีที่เจาะจงมากสำหรับฉันว่าทำไมคำสั่งนี้ไม่ทำงาน ฉันใช้เวลาในการดีบัก 12 ชั่วโมงและฉันไม่มีความคิดที่นี่

PS:ข้อผิดพลาดที่คล้ายกัน ( /usr/bin/env: node: No such file or directory) เกิดขึ้นเมื่อมีbower install(ใช้Bower ) แต่ไม่ใช่เมื่อทำงานnpm install(ใช้NPM )


เรียกใช้sh deployแทนbash deploy(อาจเป็นเรื่องน่าอาย) คุณตรวจสอบ " สิ่งต่อไปนี้ " ได้อย่างไร ฉันแนะนำให้ตรวจสอบพวกเขาในสคริปต์เพื่อให้คุณสามารถค้นพบการแทนที่ในที่สุดและการสุขาภิบาลของ envs
Giacomo Catenazzi

เกี่ยวกับ " สิ่งต่อไปนี้ ": ฉันเพิ่มพวกเขาเพื่อเริ่มสคริปต์ deploy.sh และพวกเขาส่งออกสิ่งเหล่านี้ที่ฉันถาม เอาต์พุตเดียวกันคือเมื่อฉันรันมันตามลำพัง
TomášBlatný

sh deployและbash deployทั้งคู่ก็ให้ผลลัพธ์เหมือนกัน
TomášBlatný

แสดงบรรทัดนั้นที่นี่โปรด ฉันขอแนะนำให้คุณแทนที่คำสั่งphpของคุณที่บรรทัดนี้ในสคริปต์ของคุณด้วยเอาต์พุตไปยังไฟล์เพื่อตรวจสอบตัวแปรสภาพแวดล้อมในขณะที่โทร / usr / bin / env:/usr/bin/env > environment.txt
Oleg Bolden

คำตอบ:


6

ตรวจสอบให้แน่ใจว่าการสิ้นสุดบรรทัดและ / หรือช่องว่างที่มองไม่เห็นไม่ทำให้เกิดปัญหา

ลบช่องว่างในบรรทัดแรกของสคริปต์และแทรกใหม่ตรวจสอบให้แน่ใจว่าไม่ได้กด CTRL ค้างไว้ในขณะที่กดเว้นวรรค

นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่มีจุดสิ้นสุดบรรทัด DOS (CR + LF) ดู/programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vimสำหรับรายละเอียด


ฉันกำลังใช้ IDE ซึ่งจะตรวจสอบ (และแปลง) CR + LF เป็น LF โดยอัตโนมัติเท่านั้นลบ BOM และใส่ใจเกี่ยวกับตัวอักษรสีขาว แต่ฉันตรวจสอบอีกครั้งและดูเหมือนว่าตกลง (ยังไม่ทำงาน) ขอบคุณอยู่ดี
TomášBlatný

4

วิธีที่ง่ายที่สุด .... เปลี่ยนเชลล์ของผู้ใช้เป็นสคริปต์

/ etc / passwd

Before:
deploy:x:0:0:,,,:/root:/bin/bash

After:
deploy:x:0:0:,,,:/root:/scripts/deploy.sh

สคริปต์ตัวอย่าง (ตรวจสอบให้แน่ใจว่ารันบิตถูกตั้งค่า chmod + x)

/scripts/deploy.sh

#!/bin/bash 
PATH=$PATH:/moo etc...
moo.sh

ตัวอย่าง ทำงานได้ทุกครั้ง! คุณควรจะสามารถใช้สคริปต์เพื่อแก้ไขปัญหา / แก้ไขข้อบกพร่องของตัวแปร env ใด ๆ ที่คุณอาจรู้สึกว่าไม่ได้ตั้งค่า ฯลฯ ... นอกจากนี้ข้อโต้แย้งการจัดการที่ส่งผ่านไปยัง ssh จะทำงานเช่นกัน ..

หมายเหตุ: วิธีปฏิบัติที่ดีที่สุดคือการตรวจสอบพา ธ สำหรับสคริปต์ไฟล์เอ็กซีคิวต์และอื่น ๆ ทั้งหมดข้างต้นเป็นเพียงตัวอย่างที่อนุญาตให้พา ธ เริ่มต้นถูกตั้งค่าให้เรียก moo.sh ภายในโฟลเดอร์ moo;)

ง่ายมากขอบคุณสำหรับการโพสต์ ..

การอ้างอิง: / etc / passwd รูปแบบ


คำตอบที่ดี แต่จริง ๆ แล้วฉันไม่เคยใช้ผู้ใช้บนเซิร์ฟเวอร์โดยตรงฉันมักจะsshไปที่เซิร์ฟเวอร์และโดยเลนในauthorized_keysสคริปต์ได้รับการเรียกและการเชื่อมต่อจะสิ้นสุดลง ฉันจะแก้ไขauthorized_keysเพื่อให้การทำงานนี้ทำงานได้อย่างไร
TomášBlatný

มันควรจะทำงานเหมือนกัน คุณจะตรวจสอบสิทธิ์ผ่านคีย์และตราบใดที่เชลล์ถูกตั้งค่าเป็นสคริปต์สำหรับบัญชีรีโมตที่เป็นปัญหาภายในไฟล์ / etc / passwd ของเซิร์ฟเวอร์รีโมตสคริปต์จะดำเนินการ ฉันจะเพิ่มภาพหน้าจอในโพสต์ของฉันในไม่ช้า
NotAdmin Dave

1
@Dave ไม่สามารถรอหนังสือของคุณได้
Burgi

ขอบคุณสำหรับคำตอบของคุณมันไม่ได้แก้ปัญหาของฉัน แต่เป็นสำหรับฉันที่น่าสนใจที่สุดและแก้ไขปัญหาอื่น ๆ ที่ฉันมี ให้คุณโปรดปรานขอบคุณอีกครั้ง
TomášBlatný

4

envคำสั่งจะมองผ่านผู้ใช้เป็น$PATHเพื่อหาสิ่งที่ปฏิบัติการแรกของชื่อที่กำหนด ดังนั้น/usr/bin/env phpจะค้นหาไฟล์ที่เรียกใช้งานได้ซึ่งเรียกว่าphpในไดเรกทอรีใด ๆ ในส่วน$PATHของผู้ใช้ที่เรียกใช้

ในกรณีของคุณนั้นเกือบจะแน่นอนเพราะเมื่อเรียกใช้คำสั่งsshคุณจะไม่เริ่มเชลล์เต็มและไม่อ่านไฟล์การเริ่มต้นเชลล์ของคุณจริง ๆ คุณสามารถตรวจสอบสิ่งนี้ได้ด้วยการรันคำสั่งนี้ (จดเครื่องหมายคำพูดเดี่ยว):

ssh deployer@XXX.com 'echo $PATH'

และเปรียบเทียบผลลัพธ์กับสิ่งที่คุณได้รับถ้าคุณssh deployer@XXX.comและจากนั้นecho $PATHเรียกใช้ ในระบบของฉัน ตัวอย่างเช่น:

$ echo $PATH
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:

$ ssh localhost 'echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin

ดังนั้น$PATHสคริปต์ของคุณมีสิทธิ์เข้าถึงเมื่อทำงานด้วยssh deployer@XXX.comจะไม่เหมือนกับเมื่อคุณเข้าสู่ระบบเพื่อทดสอบ

ในกรณีใด ๆ envที่เป็นวิธีง่ายๆที่จะใช้เส้นทางแบบเต็มไปล่ามแทน envเส้นทางทั้งสองและเต็มมีประโยชน์และข้อเสียแต่ในกรณีนี้เส้นทางนั้นปลอดภัยกว่า:

#!/usr/bin/php

ITYM " จดเครื่องหมายคำพูดเดี่ยว" ไม่ใช่ " ไม่ใช่ "
dave_thompson_085

@ dave_thompson_085 แน่นอนฉันทำขอบคุณ
terdon

ที่จริงฉันใช้เส้นทางเต็มทุกที่ตามที่ฉันกล่าวถึงในคำถามของฉันข้อผิดพลาดมีรายงานภายใน composer installคำสั่งซึ่งฉันไม่สามารถแก้ไขได้อย่างชัดเจน นอกจากนี้ยัง$PATHเป็น ok ที่ผมกล่าวถึงในคำถามของฉันมากเกินไปผมตรวจสอบทุกสิ่งด้วยการเพิ่มลงในสคริปต์และทำงานจากระยะไกลผ่านเข้าสู่ระบบ SSH นอกจากนี้ฉันไม่สามารถตรวจสอบssh deployer@XXX.com 'echo $PATH'ตามที่คุณระบุเนื่องจากการเข้าสู่ระบบ ssh ของฉัน จำกัด เพียงหนึ่งสคริปต์เท่านั้น แต่ฉัน hovever ตรวจสอบเมื่อฉันเพิ่ม $ PATH ลงในสคริปต์นั้น (ตามที่ระบุไว้ด้านบน) อย่างไรก็ตามขอบคุณสำหรับคำตอบของคุณและยอมรับ + 1 สำหรับการอธิบายให้ฉันenvสิ่ง
TomášBlatný

@ TomášBlatnýดีคุณกำลังใช้ env อยู่ที่ไหนสักแห่งไม่เช่นนั้นคุณจะไม่เห็นข้อผิดพลาดนั้น ฉันไม่รู้จักนักแต่งเพลง แต่คุณอาจต้องคัดลอกหรือเชื่อมโยงไฟล์ php ที่รันได้ไปยังไดเรกทอรีในพา ธ ของมัน การเรียงลำดับของสิ่งนี้ยากที่จะดีบักเนื่องจากมีหลายสิ่งที่ต่างกัน
terdon

จริงenvๆ แล้วเรียกว่าเป็นนักแต่งเพลงภายใน แต่นี่ไม่ได้แก้ปัญหาทำไมนักแต่งเพลงบางคนโทรผ่านและบางคนไม่ อย่างไรก็ตามฉันจะละเอียดกว่านี้โดยดูที่รหัส ขอบคุณสำหรับเวลาของคุณ
TomášBlatný

2

เป็นไปได้หรือไม่ว่าbashต้องรีเซ็ตเป็นตารางแฮช

หากเป็นเช่นนั้นคุณอาจลองเพิ่มhash -rบางแห่งในสคริปต์ของคุณซึ่งบังคับให้เชลล์มองผ่าน$PATHอีกครั้งแทนที่จะใช้ข้อมูล (อาจล้าสมัย) จากตารางแฮช

เมื่อจำเป็นhashยังสามารถเปิดใช้งานเชลล์เพื่อจดจำเส้นทางไปยังไฟล์ปฏิบัติการที่ติดตั้งในตำแหน่งที่ไม่ได้มาตรฐานโดยใช้-pตัวเลือกหรือลืมเส้นทางด้วย-dตัวเลือก

แหล่งที่มา:

https://unix.stackexchange.com/a/86017/121251
https://stackoverflow.com/a/22543353/2146843


นี่ไม่ได้แก้ปัญหาสำหรับฉัน แต่มันเป็นความรู้ที่ดีดังนั้นฉันจึงเพิ่ม +1 ของคุณ
TomášBlatný

1

ดูเหมือนว่าคุณอาจต้องเพิ่ม php ลงในพา ธ ของคุณ ลอง:

vim ~/.bashrc
PATH=$PATH:/usr/local/bin/php
export PATH

คุณอาจต้องการตรวจสอบที่ php ของคุณอยู่เพื่อให้แน่ใจว่าเส้นทางที่ถูกต้อง ลอง:

which php

นี่ไม่ใช่ปัญหาเนื่องจากphp -vเอาท์พุทเวอร์ชั่น PHP ที่ถูกต้องและcomposer --versionเวอร์ชั่นผู้แต่งเอาท์พุท ดังที่ฉันพูดปัญหาอยู่ในคำสั่งเดียวเท่านั้น
TomášBlatný

1

เป็นที่ชัดเจนว่าคุณมีปัญหาเส้นทางเนื่องจากสคริปต์การปรับใช้ของคุณไม่สามารถค้นหาสิ่งที่แน่นอนในเส้นทางเมื่อคุณเข้าสู่ระบบ ssh ปกติ

สิ่งแรกที่ต้องทำเพื่อยืนยันว่าคุณมีปัญหาเส้นทางคือการปรับปรุงการปรับใช้สคริปต์เพื่อเข้าสู่ระบบการส่งออกของหรืออย่างน้อยenv echo $PATHฉันคาดเดาว่าวิธีการที่สคริปต์การปรับใช้ของคุณเรียกว่า $ PATH ไม่ได้ตั้งค่าตามที่คุณคาดหวัง ผลลัพธ์การดีบักนี้จะยืนยัน / ปฏิเสธทฤษฎีของฉัน

ฉันมองไปที่การกวดวิชาที่คุณติดตาม คุณควรตรวจสอบให้แน่ใจว่าการอัปเดตcommand=เป็นcommand="/bin/sh /path/to/your/script..."ถ้าคุณยังไม่ได้ตรวจสอบให้แน่ใจว่าสคริปต์ของคุณทำงานโดยเชลล์ที่ถูกต้อง

หากคุณมีปัญหา PATH การแก้ไขด่วน / สกปรกเป็นเพียงการตั้งค่า PATH อย่างชัดเจนที่จุดเริ่มต้นของสคริปต์การปรับใช้ของคุณ

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

คำอธิบายโดยละเอียดและตัวเลือกเพิ่มเติม ...

บน linux เมื่อคำสั่งรันคำสั่งจะสืบทอดสภาพแวดล้อมของกระบวนการพาเรนต์

เมื่อคุณเข้าสู่ระบบในฐานะผู้ใช้ปกติผ่าน SSH มีหลายสิ่งที่เกิดขึ้น (เช่นการรัน / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc เป็นต้น) ณ จุดนี้คุณอาจได้อัปเดตสภาพแวดล้อมของกระบวนการโดยทำสิ่งต่างๆเช่นexport PATH="$PATH:~/mybin"ในสคริปต์เหล่านั้น ตอนนี้กระบวนการในอนาคตที่คุณเรียกใช้จะสืบทอดสภาพแวดล้อมปัจจุบันของคุณ

การรันคำสั่งแทนที่จะได้เชลล์ล็อกอินหมายความว่าคำสั่งนั้นรันโดย ssh daemon และจะสืบทอดสภาพแวดล้อมของกระบวนการ ssh daemon ... ซึ่งน่าจะแตกต่างจากสภาพแวดล้อมของคุณในฐานะผู้ใช้ที่ล็อกอิน

man page สำหรับคีย์ที่ได้รับอนุญาตครอบคลุมสิ่งที่เกิดขึ้นหลังจากการตรวจสอบสิทธิ์ เกี่ยวกับสภาพแวดล้อม:

  1. อ่านไฟล์ ~ / .ssh / environment หากมีอยู่และผู้ใช้ได้รับอนุญาตให้เปลี่ยนสภาพแวดล้อม ดูตัวเลือก PermitUserEnvironment ใน sshd_config (5)

ดังนั้นสถานที่ที่เหมาะสมในการกำหนดค่าสภาพแวดล้อมสำหรับกระบวนการอยู่ใน~/.ssh/environmentที่ซึ่ง~เป็นโฮมไดเร็กตอรี่สำหรับผู้ใช้ที่ได้รับการพิสูจน์ตัวตนเพื่อรันคำสั่ง คุณต้องตรวจสอบ sshd_config ของคุณเพื่อให้แน่ใจว่า PermitUserEnvironment ได้รับอนุญาต

~/.ssh/environment รูปแบบที่ระบุไว้ในหน้าคนแน่นอน

         This file is read into the environment at login (if it exists).
         It can only contain empty lines, comment lines (that start with
         '#'), and assignment lines of the form name=value.  The file
         should be writable only by the user; it need not be readable by
         directory becomes accessible.  This file should be writable only
         by the user, and need not be readable by anyone else.

อีกวิธีหนึ่งในการระบุสภาพแวดล้อมโดยไม่ต้องใช้วิธีการที่กล่าวถึงข้างต้นคือการใช้environment="NAME=value"ตัวเลือกในไฟล์ authorized_keys ดูหน้า man ที่ฉันลิงค์ด้านบนเพื่อดูรายละเอียด


เกี่ยวกับWithout knowing exactly how you have setup your deploy script to run: ในคำถามของฉันที่จุดเริ่มต้นมีการเชื่อมโยงฉันจะตั้งค่าได้อย่างไร (ใช้~/.ssh/authorized_keysขอบคุณสำหรับคำแนะนำในการอัปเดตคำสั่งฉันลองแล้ว แต่โชคร้ายที่ไม่มีความแตกต่างฉันจะตรวจสอบเรื่องนี้อีกครั้ง โปรดยอมรับ +1 สำหรับแนวคิดนั้น
TomášBlatný

คุณลองอัปเดตสคริปต์ปรับใช้ของคุณเพื่อพิมพ์ $ PATH ปัจจุบันหรือไม่ คุณช่วยโพสต์ผลลัพธ์ได้ไหม? หากไม่ตรงกับที่คุณคาดหวังคุณสามารถลองตั้งค่า PATH อย่างชัดเจนตามที่ฉันแนะนำไว้ในตอนต้นของสคริปต์การปรับใช้ของคุณ
mattpr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.