1

I am listing all files on my desktop using a shell script. Below is my shell script:

 #! /bin/bash

myFiles=`dir /home/chb-pc/Desktop`
#echo $myFiles;

count=0
for f in $myFiles
do 
    #echo $f 
    read myArray[$count] = f
    `expr $count + 1`
done

echo myArray

The above script will list file names of all files. I need to store the output in a variable and send it to PHP where i will loop each and every files in that variable and do some stuff.

Below is my PHP script:

<?php

$output = shell_exec("sh /home/chb-pc/Desktop/files.sh");

foreach ($output as $files) {
    echo $files . "<br>";
}
?>

I know my shell script does not seem right, but i tried various syntax and can't find the right one.

2
  • 2
    your bash script doesn't work at all, at least on Debian, as read is the command to read from stdin, why won't you just use glob() in PHP? Commented Mar 9, 2019 at 19:50
  • I didn't know about this function. Thanks for the suggestion. This makes life easier. Commented Mar 10, 2019 at 7:35

4 Answers 4

4

Just avoid using both, PHP is quite capable of listing a directory:

<?php
$dir = '/home/chb-pc/Desktop';
foreach (new DirectoryIterator($dir) as $fileInfo) {
    if($fileInfo->isDot()) continue;
    echo $fileInfo->getFilename() . "\n";
}

See: http://php.net/manual/en/class.directoryiterator.php

Sign up to request clarification or add additional context in comments.

Comments

1

You can simply use glob

$fileList = glob('temp/*');

and now you can iterate and perform your set of actions.

Comments

1

EDIT: as several others have pointed out, it's possible (and generally better) to get the list of filenames directly in php, without involving a shell script at all. But if you do need to use a shell script for some reason...

Since unix filenames can contain any character except for "/" and ASCII NUL (character #0) (and file paths can contain "/"), the standardish way to pass lists of filenames is with NUL delimiters. Getting a list of filenames from a command like ls that doesn't use a clean format like this is hard, so it's best to get the list by just using a raw wildcard (e.g. *) and letting bash itself get the list. The one slightly tricky thing in this part is that by default, if there are no matching files, the shell will just leave "*" there rather than producing an empty list, so you want bash's nullglob option enabled, and that's a bash-only feature (so run this with bash, not just sh!).

#! /bin/bash

cd /home/chb-pc/Desktop || exit

shopt -s nullglob    # If there are no files, don't just print the "*"!
printf '%s\0' *      # Print each filename followed by a NUL

There's another slightly tricky thing about capturing this in php: the list has a NUL after each filename, including the last one, but explode assumes the delimiters are between items. As a result, it'll wind up with an empty item at the end of the array, and you need to remove that with array_pop.

<?php
$output = explode("\x00", shell_exec('bash /home/chb-pc/Desktop/files.sh'));
array_pop($output);

foreach ($output as $files) {
        echo $files . "<br>";
}
?>

3 Comments

The check for the directory here /home/chb-pc/Desktop || exit does not work, you can't execute a directory. [[ -d /home/chb-pc/Desktop ]] || exit would work, but better yet would be to enable set -e (preferably set -euo pipefail) and just cd in to the directory cd /home/chb-pc/Desktop which due to set -e would exit the script if the directory didn't exist.
@lyte D'oh, that was a copy-paste error; it was supposed to be a cd command (and exit the script if cd fails for any reason). Fixed now.
Fair enough, that makes more sense now
-1

I think that an ideal solution would be if your shell script output a comma-separated list, and your PHP code would look like so:

<?php

$output = explode(',', shell_exec('sh /home/chb-pc/Desktop/files.sh');

foreach ($output as $files) {
    echo $files . "<br>";
}
?>

May that work for you?

2 Comments

probably as it's filename that are listed, much better using "\n" as separator... otherwise you'll have to escape commas from filenames. And bash script could probably be remplace by a simple "find /my/dir"
using \n as a separator would also mean you have to do escaping for files containing the newline character, better would be \0, as files are not allowed to contain that character

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.