0

I have a script that logs in to a remote host to pull a directory listing to later present options to the user. It was all working perfectly, until some of the directories started having spaces in them. I have tried several syntaxes and googled the life out of this and I am now at the end of my tether. The original command was this:

SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | awk '{print $8}'))

I first off changed this code to be able to read the spaces like this:

SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-))

However This resulted in each word being recognised as a variable. I have tried many ways to try to solve this, two of which were:

SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -d $FROMFOLDER*  |rev| cut -d'/' -f1|rev|sed s/^/\"/g|sed s/$/\"/g))
SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -d $FROMFOLDER*  |rev| cut -d'/' -f1|rev|sed 's/ /\\ /g'))
SERVERDIRS=(`sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -d $FROMFOLDER*  |rev| cut -d'/' -f1|rev|sed 's/ /\\ /g'`)

How can I resolve these directories in to separate elements correctly?

fileinsert
  • 431
  • 4
  • 22
  • 1
    I'm not sure if it will work but you could try changing $IFS to something other than space so that the spaces don't cause the script to parse the space separated string as separate attibutes? [this may help](http://stackoverflow.com/questions/4128235/bash-shell-scripting-what-is-the-exact-meaning-of-ifs-n) – andrew Feb 24 '15 at 01:55
  • I would start by the most obvious thing, double quoting your variables to prevent the whitespace problems. "$FROMFOLDER" should do the trick i guess. – tvm Feb 24 '15 at 01:55

2 Answers2

1

If you're trying to read one array value per line instead of space-separated, then $() syntax won't help. Try readarray (Bash 4):

readarray SERVERDIRS < <(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-)

or assign IFS and read with -d, -r, and -a set:

IFS=$'\n' read -d '' -r -a SERVERDIRS < <(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER@$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-)

or, really, any other answer to this SO question.

If you're unfamiliar with <() syntax, it's known as process substitution and will allow your variable to be set in your current environment rather than the instantly-discarded subshell that a pipe would create.

Bear in mind that this process is a little dangerous; filenames can also contain newlines, so it's usually much preferred to use find ... -print0.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • The readarray option did not work but I eventually got it to work by reassigning IFS to new line (and putting back to normal after, of course). Seems a bit hacky, but gets the job done. Thanks! – fileinsert Feb 25 '15 at 00:33
-1

If you only need to list directories, try this

ls -d /usr/local/src/*/

or

ls -d /path/to/your/directory/*/

You can then loop through all directories

#!/bin/bash

aa=`ls -d /usr/local/src/*/`

for dir in "${aa}[@]"
do
  echo "$dir"
done

This works if dir names contain spaces.

candymanuu
  • 110
  • 7