Build Unix command line tools ls,cat,touch,find,vi and mkdir using php

ls

Safaetul Ahasan
4 min readMay 29, 2023

To build a simple version of the ls command line tool using PHP, we can use the built-in scandir() function to list the files and directories in a given directory. Here's an example implementation:

<?php
function ls($directory = '.')
{
$files = scandir($directory);

foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}

echo $file . PHP_EOL;
}
}

// Usage: php ls.php [directory]
// If no directory is specified, the current directory will be used.
$directory = isset($argv[1]) ? $argv[1] : '.';
ls($directory);
?>

Save the above code in a file named ls.php. You can then run the tool from the command line using php ls.php to list the files and directories in the current directory, or php ls.php /path/to/directory to list the contents of a specific directory.

cat

To build a basic version of the cat command line tool using PHP, we can use the file_get_contents() function to read the content of a file and echo it to the console. Here's an example implementation:

<?php
function cat($filename)
{
$content = file_get_contents($filename);

if ($content === false) {
echo "Error reading file: $filename" . PHP_EOL;
} else {
echo $content;
}
}

// Usage: php cat.php [filename]
// Replace [filename] with the path to the file you want to read.
if (isset($argv[1])) {
$filename = $argv[1];
cat($filename);
} else {
echo "Usage: php cat.php [filename]" . PHP_EOL;
}
?>

Save the above code in a file named cat.php. You can then run the tool from the command line using php cat.php /path/to/file to display the content of the specified file.

touch

<?php
function touchFile($filename)
{
if (file_exists($filename)) {
// If the file already exists, update its timestamp
touch($filename);
echo "Updated timestamp of file: $filename" . PHP_EOL;
} else {
// If the file does not exist, create a new empty file
if (touch($filename)) {
echo "Created new file: $filename" . PHP_EOL;
} else {
echo "Error creating file: $filename" . PHP_EOL;
}
}
}

// Usage: php touch.php [filename]
// Replace [filename] with the name of the file you want to create or update.
if (isset($argv[1])) {
$filename = $argv[1];
touchFile($filename);
} else {
echo "Usage: php touch.php [filename]" . PHP_EOL;
}
?>

Save the above code in a file named touch.php. You can then run the tool from the command line using php touch.php filename to create a new file or update the timestamp of an existing file.

vi

<?php
function vi($filename)
{
if (!is_file($filename)) {
echo "File does not exist: $filename" . PHP_EOL;
return;
}

$content = file_get_contents($filename);
echo "Starting 'vi'. Use ':q' to save and exit." . PHP_EOL;
echo "--------------------------------------------------" . PHP_EOL;
echo $content . PHP_EOL;
echo "--------------------------------------------------" . PHP_EOL;

$lines = explode("\n", $content);

$stdin = fopen('php://stdin', 'r');
$output = '';
$lineNumber = 0;

while (true) {
echo "vi: $lineNumber > ";
$line = trim(fgets($stdin));

if ($line === ':q') {
// Save and exit
file_put_contents($filename, $output);
echo "Saved file: $filename" . PHP_EOL;
break;
}

$output .= $line . PHP_EOL;
$lineNumber++;
}

fclose($stdin);
}

// Usage: php vi.php [filename]
// Replace [filename] with the path to the file you want to edit.
if (isset($argv[1])) {
$filename = $argv[1];
vi($filename);
} else {
echo "Usage: php vi.php [filename]" . PHP_EOL;
}
?>

Save the above code in a file named vi.php. You can then run the tool from the command line using php vi.php /path/to/file to edit the specified file.

mkdir

<?php
function mkdirCommand($directory)
{
if (is_dir($directory)) {
echo "Directory already exists: $directory" . PHP_EOL;
} else {
if (mkdir($directory, 0755, true)) {
echo "Created directory: $directory" . PHP_EOL;
} else {
echo "Error creating directory: $directory" . PHP_EOL;
}
}
}

// Usage: php mkdir.php [directory]
// Replace [directory] with the name of the directory you want to create.
if (isset($argv[1])) {
$directory = $argv[1];
mkdirCommand($directory);
} else {
echo "Usage: php mkdir.php [directory]" . PHP_EOL;
}
?>

Save the above code in a file named mkdir.php. You can then run the tool from the command line using php mkdir.php directory to create a new directory.

Find

<?php
function find($directory)
{
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory),
RecursiveIteratorIterator::SELF_FIRST
);

foreach ($iterator as $item) {
$path = $item->getPathname();

if ($item->isDir()) {
echo "[DIR] $path" . PHP_EOL;
} else {
echo "[FILE] $path" . PHP_EOL;
}
}
}

// Usage: php find.php [directory]
// Replace [directory] with the path to the directory you want to search.
if (isset($argv[1])) {
$directory = $argv[1];
find($directory);
} else {
echo "Usage: php find.php [directory]" . PHP_EOL;
}
?>

Save the above code in a file named find.php. You can then run the tool from the command line using php find.php /path/to/directory to list the files and directories in the specified directory and its subdirectories.

This implementation uses the RecursiveDirectoryIterator class to iterate over the directory and its subdirectories recursively. The RecursiveIteratorIterator is used to flatten the nested structure and provide a simple iterator for traversal. It prints each file and directory encountered along with their paths, marking directories with [DIR] and files with [FILE].

--

--