สคริปต์บรรทัดคำสั่งที่ทำงานในพื้นหลังจะอยู่ในสถานะหยุดทำงาน

ฉันมีสคริปต์ยูทิลิตี้ php สั้น ๆ ฉันเรียกใช้จาก cli ง่ายๆด้วย:

php myscript.php

สคริปต์ทำงานอยู่เสมอ โดยทำงานบางอย่างเป็นระยะ (ไม่เกี่ยวข้องกับคำถาม) ไม่ต้องการอินพุตใด ๆ จากผู้ใช้ หลังจากรันแล้ว ฉันมักจะกด CTRL+z จากนั้นรัน bg เพื่อวางกระบวนการไว้ในเบื้องหลัง และทุกอย่างเรียบร้อยดี

ถ้าฉันรันมันเป็น:

php myscript.php &

สคริปต์วางอยู่บนพื้นหลังเมื่อเริ่มต้น แต่ยังอยู่ในสถานะหยุดทำงานด้วย ตัวอย่าง:

[1] 11513
[1]+  Stopped                 php myscript.php

แม้การเรียกใช้ bg ณ จุดนี้ไม่ได้ช่วยอะไร ฉันต้องเรียกใช้ fg จากนั้น CTRL+z และ bg อีกครั้งเพื่อให้มันใช้งานได้

นี่คือสคริปต์ php:

<?
while(true){
    echo 'hi '.time()."\n";
    sleep(30);
}
?>

ปัญหาของฉันคือฉันไม่สามารถรันมันในเบื้องหลังได้โดยตรง เพราะระบบหยุดมัน และฉันไม่เข้าใจว่าทำไม ฉันจะแก้ไขปัญหานี้ได้อย่างไร?

อัปเดต:

ฉันสร้างสคริปต์เดียวกันในเวอร์ชัน bash และสามารถเรียกใช้และวางไว้ในพื้นหลังได้ (ทำงานและไม่หยุด) เพียงแค่เปิดใช้งานด้วย & ในตอนท้าย (script.sh &)

script.sh:

#!/bin/bash
while true; do
    echo `date`
    sleep 30
done

เหตุใดสคริปต์ php จึงหยุดทำงานหลังจากเปิดใช้งานในเบื้องหลัง และสคริปต์ทุบตีไม่ทำงาน อะไรทำให้เกิดพฤติกรรมที่แตกต่างออกไปนี้


person Lorenzo Marcon    schedule 28.07.2013    source แหล่งที่มา
comment
เป็นการดีที่จะทราบเหตุผลจากผู้ใช้ที่โหวตให้ปิดคำถาม   -  person Lorenzo Marcon    schedule 28.07.2013
comment
ประการแรก สิ่งนี้ไม่มีความเกี่ยวข้องที่ชัดเจนกับการบริหารระบบอย่างมืออาชีพ ประการที่สอง คุณบอกว่างานในสคริปต์ของคุณไม่เกี่ยวข้องกับคำถาม แต่ค่อนข้างชัดเจนว่างานเหล่านั้นเกี่ยวข้องและควรได้รับการอธิบาย   -  person Michael Hampton    schedule 28.07.2013
comment
เหตุใดจึงชัดเจน? ถ้าฉันบอกว่ามันไม่เกี่ยวข้อง มัน ไม่: สคริปต์มี a while(true) with a sleep :) อย่างไรก็ตาม ฉันเพิ่มมันเข้าไปในคำถามของฉัน ดังนั้นมันจึงสามารถช่วยให้เข้าใจได้ มันเกี่ยวข้องอย่างไร (ไม่) สำหรับวัตถุประสงค์ของคำถามนั้น ไม่เกี่ยวข้องกับงานที่จะดำเนินการ มันเชื่อมต่อโดยตรงกับการดูแลระบบระดับมืออาชีพ เพราะฉันใช้สคริปต์นี้ในเซิร์ฟเวอร์ linux ตัวใดตัวหนึ่งของฉัน (เพื่อวัตถุประสงค์ในการสำรองข้อมูล เพื่อเพิ่มรายละเอียด)   -  person Lorenzo Marcon    schedule 28.07.2013


คำตอบ (3)


โดยปกติแล้ว กระบวนการที่คุณส่งอะไรไปที่พื้นหลังด้วย & และสคริปต์ที่รออินพุตจากเทอร์มินัลจะเข้าสู่สถานะหยุดทำงาน

เช่น. มีสคริปต์ทุบตี valecho:

#!/bin/sh
read val
echo $val

เรียกใช้เป็น:

./valecho &

สคริปต์จะหยุด

เมื่อรันมันเป็น

echo hello | ./valecho &

จะทำงานได้อย่างถูกต้องและเสร็จสิ้น

ดังนั้นตรวจสอบ php ของคุณ - อาจต้องการอินพุตจาก stdin

แก้ไข - ตามความคิดเห็น:

ฉันไม่ใช่นักพัฒนา php - แต่เพิ่งลองใช้สคริปต์ถัดไป (p.php)

<?php
    while(true){
        echo 'hi '.time()."\n";
        sleep(3);
    }
?>

ด้วยคำสั่ง:

php -f p.php &

และดำเนินไปด้วยดี... ดังนั้น... ขออภัยในความสับสน...

person jm666    schedule 28.07.2013
comment
ขอบคุณ แต่ฉันไม่คิดว่าจะเป็นเช่นนี้เพราะสคริปต์ไม่รอการป้อนข้อมูลจากผู้ใช้ คุณสามารถดูรหัสได้ในคำถามของฉัน มันสั้นมาก นอกจากนี้หากฉันวางไว้เบื้องหน้าและเบื้องหลังโดยไม่ใส่อินพุตใด ๆ มันก็ใช้งานได้ .. เป็นไปได้อย่างไร? - person Lorenzo Marcon; 29.07.2013
comment
@LorenzoMarcon ดูการแก้ไข - ใช้งานได้สำหรับฉัน ... (มีการติดตั้ง php เริ่มต้นเท่านั้น) - person jm666; 29.07.2013
comment
ขอบคุณอีกครั้ง ปัญหาคือบนพีซีของฉันก็ใช้งานได้เหมือนกัน แต่บนเซิร์ฟเวอร์กลับใช้ไม่ได้... ฉันกำลังตรวจสอบความแตกต่าง - person Lorenzo Marcon; 29.07.2013
comment
@LorenzoMarcon - เคล็ดลับเท่านั้น: set_time_limit(0); ? - person jm666; 29.07.2013
comment
ฉันพบสิ่งที่ทำให้เกิดปัญหา และเขียนคำตอบ เนื่องจากคุณให้ข้อมูลที่ถูกต้องแก่ฉัน (readline) ฉันจะให้คำตอบที่ได้รับการยอมรับ :) ขอบคุณ! - person Lorenzo Marcon; 29.07.2013
comment
@LorenzoMarcon ขอบคุณ - และสนุกกับสคริปต์ของคุณ ;) - person jm666; 29.07.2013

ฉันพบสิ่งที่ทำให้เกิดปัญหา ใน PHP หากเปิดใช้งานโมดูล Readline สคริปต์บรรทัดคำสั่งใดๆ จะคาดหวังอินพุต แม้ว่าสคริปต์จะถูกเขียนเพื่อไม่ให้รออินพุตจากผู้ใช้ก็ตาม

หากต้องการตรวจสอบว่าคุณเปิดใช้งานการสนับสนุน readline หรือไม่ ให้เรียกใช้:

php --info |grep "Readline Support"

และตรวจสอบผลลัพธ์ หากคุณได้รับ Readline Support => enabled แสดงว่าคุณได้เปิดใช้งานการอ่านข้อมูลแล้ว และคุณอาจประสบปัญหาตามที่อธิบายไว้ในคำถามเดิม

วิธีที่เหมาะสมในการใช้ cli คือเมื่อใดให้ระบุอย่างชัดเจนว่า php ไม่ได้ใช้เทอร์มินัลในการป้อนข้อมูล:

php myscript.php < /dev/null &

ข้อมูลเพิ่มเติม: http://php.net/manual/en/book.readline.php

ทางเลือก:

./test.php >/dev/null &    

หรือ (สร้างสรรค์มากขึ้น):

nohup php test.php > /dev/null 2>&1 &

(ปล.: ฉันยังคงเชื่อว่าคำถามนี้เป็นของ ServerFault อย่างไรก็ตาม .. แก้ไขปัญหาแล้ว!)

person Lorenzo Marcon    schedule 29.07.2013
comment
ฉันมีปัญหาเดียวกัน PHP ของฉันมาจาก yum และไม่ได้คอมไพล์ ฉันจะปิดการใช้งาน readline ได้อย่างไร? - person DOOManiac; 03.01.2014
comment
คุณพยายามลบแพ็คเกจ php-readline (หากติดตั้ง) หรือไม่ - person Lorenzo Marcon; 04.01.2014
comment
php myscript.php < /dev/null & แก้ไขปัญหานี้ให้ฉันแล้ว ขอบคุณสำหรับคำอธิบายแบบอ่านง่าย - person Liam; 20.03.2014

จาก http://php.net/manual/en/book.readline.php :

เมื่อเปิดใช้งาน readline php จะเปลี่ยนโหมดเทอร์มินัลเพื่อยอมรับอินพุตบัฟเฟอร์บรรทัด ซึ่งหมายความว่าวิธีที่เหมาะสมในการใช้ cli เมื่อคุณไพพ์ไปยังคำสั่งแบบโต้ตอบคือการระบุอย่างชัดเจนว่า php ไม่ได้ใช้เทอร์มินัลในการป้อนข้อมูล:

php myscript.php < /dev/null &

แหล่งที่มา

person Chris Montanaro    schedule 08.08.2013