PHP로 명령줄 스크립트 작성하기: 파트 2, STDIN 읽기
이 일련의 기사에서 우리는 php에서 고품질 스크립트를 빌드하는 데 도움이 되는 다양한 기술과 구조를 살펴볼 것입니다.
이 기사는 표준 입력에서 읽는 데 중점을 둡니다.
이전 할부
이것은 시리즈의 두 번째 할부입니다. 첫 번째 기사에서는 명령줄 인수 구문 분석, 현재 환경에서 실행될 수 있도록 스크립트 사전 실행, 스크립트 디자인의 일부 세부 사항 처리에 대해 다루었습니다.
(지금까지) 이 시리즈를 구성하는 기사는 다음과 같습니다.
비행
여기에서는
STDIN
스트림에서 파이프로 연결된 데이터를 읽는 예제 스크립트를 설계할 것입니다. 이 기능을 사용하려면 다음 두 가지 작업을 수행해야 합니다.STDIN
에 있는지 테스트합니다.STDIN
입력STDIN
또는 STDOUT
와 같은 Linux 데이터 스트림에 익숙하지 않은 경우 spend a few minutes reading up on them 먼저 하는 것이 좋습니다.파이프 입력 읽기
명령줄 스크립트는 종종
STDIN
에서 파이프된 대로 입력을 받습니다. bash
대신 fish shell을 사용하는 시스템의 모든 사용자를 찾는 이 짧은 작은 파이프라인을 고려하십시오.$ cat /etc/passwd | grep "bin/fish"
gbhorwood:x:1000:1000:grant horwood,,,:/home/gbhorwood:/usr/bin/fish
cat
명령은 파일의 내용을 STDOUT
로 덤프합니다. 일반적으로 STDOUT
는 터미널로 이동하여 읽을 수 있지만 이 예에서는 |
연산자(파이프)가 STDOUT
의 내용을 트랩하고 오른쪽에 있는 다음 명령의 입력으로 사용합니다. 파이프 연산자는 기본적으로 왼쪽 명령의 출력을 오른쪽 명령의 입력으로 '파이프'합니다. 그래서 '파이프'라고 합니다.이것은 편리한 기능이며 PHP 스크립트에서 구현하려는 기능입니다.
ourfancyscript.php
에 추가할 이 함수로 그렇게 해 봅시다.#!/usr/bin/env php
<?php
/**
* Read contents piped in from STDIN stream
*
* @return String
*/
function read_piped_input()
{
$piped_input = null;
while ($line = fgets(STDIN)) { // noted STDIN here is not a string
$piped_input .= $line;
}
return (string) $piped_input;
}
/**
* Entry point
*/
$my_piped_in_content = read_piped_input();
print "piped input is:".PHP_EOL;
print $my_piped_in_content;
read_piped_input()
함수를 살펴보겠습니다. 여기서 핵심 기능은 fgets
을 사용하여 내용이 소진될 때까지 루프의 STDIN
포인터에서 한 줄씩 읽는 것입니다. 해당 줄은 함께 연결되어 반환됩니다. 임무 완수.어떻게 실행되는지 봅시다.
echo "this is our piped input" | ./ourfancyscript.php
piped input is:
this is our piped input
정확히 우리가 기대하는 것.
파이프 입력 테스트
제외하고 문제가 있습니다.
ourfancyscript.php
에 대한 입력 없이 STDIN
를 실행하면 중단됩니다. 왜요? 결코 오지 않는 입력을 참을성 있게 기다리고 있기 때문입니다.이를 해결하기 위해
STDIN
에 입력이 있는지 여부를 테스트하고 true를 반환하는 경우에만 파이프에서 읽는 함수를 작성할 것입니다./**
* Test if there is input waiting on STDIN
*
* @return bool
*/
function test_piped_input()
{
$streams = [STDIN]; // note STDIN here is not a string
$write_array = [];
$except_array = [];
$seconds = 0; // zero seconds on timeout since this is just for testing stream change
$streamCount = @stream_select($streams, $write_array, $except_array, $seconds);
return (boolean) $streamCount;
}
이 기능의 핵심은
stream_select
명령입니다. stream_select
는 기본적으로 스트림의 상태가 변경될 때까지 대기하며 $seconds
가 지나면 시간 초과됩니다.관심 있는 스트림이기 때문에 배열의 유일한 요소로
STDIN
에 전달하고 제한 시간$seconds
을 0으로 설정합니다. STDIN
입력이 있거나 없기 때문에 0초를 사용합니다. 스크립트를 실행하기도 전에. 그것을 기다리는 것은 의미가 없습니다. 거기에 있든 없든.우리의 명령에 파이프된 데이터가 있는 경우
STDIN
는 정의에 따라 '변경'되었으며 stream_select
는 0이 아닌 숫자를 반환합니다. 데이터가 우리를 기다리고 있다는 것을 알고 있습니다! 데이터가 없으면 스트림은 변경되지 않고 반환값은 0입니다.함께 넣어
이제
test_piped_input()
및 read_piped_input()
가 있으므로 스크립트에 함께 넣을 수 있습니다./**
* Entry point
*/
if (test_piped_input()) {
$my_stdin_content = read_piped_input();
print "piped input is:".PHP_EOL;
print $my_stdin_content;
}
이제 파이프 연결 스트림 없이 실행하면
ourfancyscript.php
진행됩니다. 데이터를 파이프하면 데이터가 처리됩니다.이제 전체 스크립트를 살펴보겠습니다.
#!/usr/bin/env php
<?php
/**
* Test if there is input waiting on STDIN
*
* @return bool
*/
function test_piped_input()
{
$streams = [STDIN]; // note STDIN here is not a string
$write_array = [];
$except_array = [];
$seconds = 0; // zero seconds on timeout since this is just for testing stream change
$streamCount = @stream_select($streams, $write_array, $except_array, $seconds);
return (boolean) $streamCount;
}
/**
* Read contents piped in from STDIN stream
*
* @return String
*/
function read_piped_input()
{
$piped_input = null;
while ($line = fgets(STDIN)) {
$piped_input .= $line;
}
return (string) $piped_input;
}
/**
* Entry point
*/
if (test_piped_input()) {
$my_stdin_content = read_piped_input();
print "piped input is:".PHP_EOL;
print $my_stdin_content;
}
다음 단계
우리 스크립트에 입력을 효과적으로 받는 데는 여전히 다루어야 할 더 많은 근거가 있습니다. 앞으로는 대화식 입력에 대해 살펴보겠습니다.
Reference
이 문제에 관하여(PHP로 명령줄 스크립트 작성하기: 파트 2, STDIN 읽기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/gbhorwood/writing-command-line-scripts-in-php-part-2-reading-stdin-2enf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)