CLI 라이브러리

CodeIgniter의 CLI 라이브러리는 다음과 같이 대화형 명령줄 스크립트 작성을 쉽게 해 줍니다:

  • 사용자에게 추가 정보를 묻기

  • 터미널에 여러 색상의 텍스트 쓰기

  • 삑 소리 내기(예의 있게 사용하세요!)

  • 긴 작업 중 진행률 표시줄 표시

  • 긴 텍스트 줄을 창 크기에 맞게 줄바꿈하기.

클래스 초기화

CLI 라이브러리는 모든 메서드가 정적이므로 인스턴스를 생성할 필요가 없습니다. 대신 클래스 위의 use 구문으로 컨트롤러가 이를 찾을 수 있도록만 하면 됩니다:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class MyCommand extends BaseCommand
{
    // ...

    public function run(array $params)
    {
        // ...
    }
}

이 클래스는 파일이 처음 로드될 때 자동으로 초기화됩니다.

사용자로부터 입력 받기

때때로 사용자에게 더 많은 정보를 물어야 합니다. 사용자가 선택적 명령줄 인자를 제공하지 않았거나, 스크립트가 기존 파일을 만나 덮어쓰기 전에 확인이 필요할 수 있습니다. 이는 prompt() 또는 promptByKey() 메서드로 처리합니다.

참고

v4.3.0부터는 PhpStreamWrapper로 이 메서드들을 테스트할 수 있습니다. CLI 입력 테스트을 참고하세요.

prompt()

첫 번째 매개변수로 질문을 전달할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

$color = CLI::prompt('What is your favorite color?');

두 번째 매개변수로 기본값을 전달하면 사용자가 그냥 Enter를 눌렀을 때 그 값이 사용됩니다:

<?php

use CodeIgniter\CLI\CLI;

$color = CLI::prompt('What is your favorite color?', 'blue');

두 번째 매개변수로 허용된 답변 배열을 전달하여 가능한 답변을 제한할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

$overwrite = CLI::prompt('File exists. Overwrite?', ['y', 'n']);

마지막으로, 세 번째 매개변수로 입력값에 대한 validation 규칙을 전달할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

$email = CLI::prompt('What is your email?', null, 'required|valid_email');

검증 규칙은 배열 구문으로도 작성할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

$email = CLI::prompt('What is your email?', null, ['required', 'valid_email']);

promptByKey()

prompt의 미리 정의된 답변(옵션)은 설명이 필요하거나 값으로 선택하기에는 너무 복잡할 수 있습니다. promptByKey()는 사용자가 값 대신 키로 옵션을 선택할 수 있게 해 줍니다:

<?php

use CodeIgniter\CLI\CLI;

$fruit = CLI::promptByKey('These are your choices:', ['The red apple', 'The plump orange', 'The ripe banana']);
/*
 * These are your choices:
 *   [0]  The red apple
 *   [1]  The plump orange
 *   [2]  The ripe banana
 *
 * [0, 1, 2]:
 */

이름이 있는 키도 가능합니다:

<?php

use CodeIgniter\CLI\CLI;

$fruit = CLI::promptByKey(['These are your choices:', 'Which would you like?'], [
    'apple'  => 'The red apple',
    'orange' => 'The plump orange',
    'banana' => 'The ripe banana',
]);
/*
 * These are your choices:
 *   [apple]   The red apple
 *   [orange]  The plump orange
 *   [banana]  The ripe banana
 *
 * Which would you like? [apple, orange, banana]:
 */

마지막으로, 세 번째 매개변수로 입력값에 대한 validation 규칙을 전달할 수 있으며, 허용 가능한 답변은 전달된 옵션으로 자동 제한됩니다.

promptByMultipleKeys()

Added in version 4.3.0.

이 메서드는 promptByKey()와 같지만 여러 값을 지원합니다.

<?php

use CodeIgniter\CLI\CLI;

$hobbies = CLI::promptByMultipleKeys('Select your hobbies:', ['Playing game', 'Sleep', 'Badminton']);
/*
 * Select your hobbies:
 *   [0]  Playing game
 *   [1]  Sleep
 *   [2]  Badminton
 *
 * You can specify multiple values separated by commas.
 * [0, 1, 2]:
 *
 * if your answer is '0,2', the return is the key and the value of the options :
 * [
 *   [0] => "Playing game",
 *   [2] => "Badminton"
 * ]
 */

중요

promptByMultipleKeys() 메서드는 promptByKey()와 달리 이름이 있는 키나 검증을 지원하지 않습니다.

피드백 제공

write()

사용자에게 피드백을 제공할 수 있는 여러 메서드가 있습니다. 단순한 상태 업데이트부터 사용자의 터미널 창 너비에 맞춰 줄바꿈되는 복잡한 정보 표까지 가능합니다. 핵심은 출력할 문자열을 첫 번째 매개변수로 받는 write() 메서드입니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::write('The rain in Spain falls mainly on the plains.');

두 번째 매개변수로 색상 이름을 전달하면 텍스트 색상을 바꿀 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::write('File created.', 'green');

이를 사용하면 상태별로 메시지를 구분하거나 다른 색으로 ‘헤더’를 만들 수 있습니다. 세 번째 매개변수로 색상 이름을 전달해 배경색도 설정할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::write('File overwritten.', 'light_red', 'dark_gray');

다음 전경색을 사용할 수 있습니다:

  • 검은색

  • 짙은 회색

  • 파란색

  • 짙은 파란색

  • 연한 파란색

  • 초록색

  • 연한 초록색

  • 청록색

  • 연한 청록색

  • 빨간색

  • 연한 빨간색

  • 보라색

  • 연한 보라색

  • 연한 노란색

  • 노란색

  • 연한 회색

  • 흰색

배경색으로는 더 적은 수를 사용할 수 있습니다:

  • 검은색

  • 파란색

  • 초록색

  • 청록색

  • 빨간색

  • 노란색

  • 연한 회색

  • 자홍색

print()

write() 메서드와 동일하게 동작하지만, 앞뒤로 줄바꿈을 강제하지 않습니다. 대신 현재 커서 위치에 화면으로 출력합니다. 따라서 서로 다른 호출에서 여러 항목을 같은 줄에 연속해서 출력할 수 있습니다. 상태를 보여 준 뒤 작업을 수행하고 같은 줄에 “Done”을 출력하고 싶을 때 특히 유용합니다:

<?php

use CodeIgniter\CLI\CLI;

for ($i = 0; $i <= 10; $i++) {
    CLI::print($i);
}

color()

write() 명령은 EOL 문자로 끝나는 한 줄을 터미널에 출력하지만, color() 메서드를 사용하면 같은 방식으로 사용할 수 있는 문자열 조각을 만들 수 있습니다. 다만 출력 후 EOL을 강제하지 않습니다. 이를 통해 같은 행에 여러 출력을 만들 수 있습니다. 더 흔하게는 write() 메서드 안에서 다른 색상의 문자열을 만들 때 사용할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::write("fileA \t" . CLI::color('/path/to/file', 'white'), 'yellow');

이 예제는 창에 한 줄을 출력하며, fileA 는 노란색으로, 그 뒤에 탭을 두고, /path/to/file 은 흰색 텍스트로 표시됩니다.

error()

오류를 출력해야 한다면 그에 맞는 이름의 error() 메서드를 사용해야 합니다. 이 메서드는 write()color()처럼 STDOUT이 아니라 STDERR에 연한 빨간색 텍스트를 출력합니다. 오류를 감시하는 스크립트가 전체 정보 대신 실제 오류 메시지만 걸러 보게 하고 싶을 때 유용합니다. 사용법은 write() 메서드와 동일합니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::error('Cannot write to file: ' . $file);

wrap()

이 명령은 문자열을 받아 현재 줄부터 출력하고, 지정한 길이가 되면 다음 줄로 줄바꿈합니다. 현재 창에서 줄이 화면 밖으로 넘어가지 않게 설명이 있는 옵션 목록을 표시할 때 유용할 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::color("task1\t", 'yellow');
CLI::wrap('Some long description goes here that might be longer than the current window.');

기본적으로 문자열은 터미널 너비에 맞춰 줄바꿈됩니다. Windows는 현재 창 크기를 확인할 방법을 제공하지 않으므로 기본값은 80자입니다. 창 안에 확실히 들어갈 정도로 더 짧은 너비로 제한하려면 두 번째 매개변수로 최대 줄 길이를 전달하세요. 그러면 단어가 깨지지 않도록 가장 가까운 단어 경계에서 문자열이 나뉩니다.

<?php

use CodeIgniter\CLI\CLI;

// Wrap the text at max 20 characters wide
CLI::wrap($description, 20);

제목, 파일, 작업을 왼쪽 열에 두고, 그 설명을 오른쪽 열에 두고 싶을 수 있습니다. 기본적으로는 창의 왼쪽 가장자리로 다시 줄바꿈되므로 열을 맞춰 정렬할 수 없습니다. 이런 경우 첫 줄 뒤의 각 줄에 공백 수를 지정해 들여쓰기하면 왼쪽 경계를 깔끔하게 맞출 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

$titles = [
    'task1a',
    'task1abc',
];
$descriptions = [
    'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
    "Lorem Ipsum has been the industry's standard dummy text ever since the",
];

// Determine the maximum length of all titles
// to determine the width of the left column
$maxlen = max(array_map('strlen', $titles));

for ($i = 0; $i < count($titles); $i++) {
    CLI::write(
        // Display the title on the left of the row
        substr(
            $titles[$i] . str_repeat(' ', $maxlen + 3),
            0,
            $maxlen + 3,
        ) .
        // Wrap the descriptions in a right-hand column
        // with its left side 3 characters wider than
        // the longest item on the left.
        CLI::wrap($descriptions[$i], 40, $maxlen + 3),
    );
}

다음과 같이 표시됩니다:

task1a     Lorem Ipsum is simply dummy
           text of the printing and
           typesetting industry.
task1abc   Lorem Ipsum has been the
           industry's standard dummy
           text ever since the

newLine()

newLine() 메서드는 사용자에게 빈 줄을 표시합니다. 이 메서드는 매개변수를 받지 않습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::newLine();

clearScreen()

clearScreen() 메서드로 현재 터미널 창을 지울 수 있습니다. 대부분의 Windows 버전에서는 이 기능을 지원하지 않으므로 단순히 빈 줄 40개를 삽입합니다. Windows 10의 bash 통합에서는 달라질 수 있습니다:

<?php

use CodeIgniter\CLI\CLI;

CLI::clearScreen();

showProgress()

오래 걸리는 작업의 진행 상황을 사용자에게 계속 보여 주고 싶다면 다음과 같은 내용을 표시하는 showProgress() 메서드를 사용할 수 있습니다:

[####......] 40% Complete

이 블록은 제자리에서 애니메이션되어 꽤 멋진 효과를 냅니다.

사용하려면 현재 단계를 첫 번째 매개변수로, 전체 단계 수를 두 번째 매개변수로 전달하세요. 완료율과 표시 길이는 그 숫자를 기준으로 결정됩니다. 작업이 끝나면 첫 번째 매개변수로 false를 전달하면 진행 표시줄이 제거됩니다.

<?php

use CodeIgniter\CLI\CLI;

$totalSteps = count($tasks);
$currStep   = 1;

foreach ($tasks as $task) {
    CLI::showProgress($currStep++, $totalSteps);
    $task->run();
}

// Done, so erase it...
CLI::showProgress(false);

table()

<?php

use CodeIgniter\CLI\CLI;

$thead = ['ID', 'Title', 'Updated At', 'Active'];
$tbody = [
    [7, 'A great item title', '2017-11-15 10:35:02', 1],
    [8, 'Another great item title', '2017-11-16 13:46:54', 0],
];

CLI::table($tbody, $thead);
+----+--------------------------+---------------------+--------+
| ID | Title                    | Updated At          | Active |
+----+--------------------------+---------------------+--------+
| 7  | A great item title       | 2017-11-16 10:35:02 | 1      |
| 8  | Another great item title | 2017-11-16 13:46:54 | 0      |
+----+--------------------------+---------------------+--------+

wait()

지정한 초만큼 대기하며, 필요하면 대기 메시지를 표시하고 키 입력을 기다립니다.

<?php

use CodeIgniter\CLI\CLI;

// wait for specified interval, with countdown displayed
CLI::wait($seconds, true);

// show continuation message and wait for input
CLI::wait(0, false);

// wait for specified interval
CLI::wait($seconds, false);