0

I need to access array which is dynamically created.

First look into the code:

ssh username@11.22.333.44 <<'ENDSSH'
cd /home/ubuntu/user/someFolder
array=(`find . -name 'something*'`)
len=${#array[*]}

i=0
while [ $i -lt $len ]; do
    let i++
done
echo  "${array[*]}"  #here I can access array values
ENDSSH
#Just above i have exited from ssh & now I need to access array values but not getting.
echo  "${array[*]}" #here I'm unable to get array values
exit

My concern is to access array after ENDSSH.

  • 2
    That array existed in the memory of the shell that ran on the remote host, not in the shell on the local host. – Andy Dalton Jul 3 '18 at 14:35
  • @AndyDalton So is there any way by which I can access outside remote host? – Shubham Kumar Rohit Jul 3 '18 at 14:35
  • 1
    You are constructing array on the remote host. You'll need to transmit the data back to the local host. Probably the easiest thing to do is to serialize it and write it to stdout, then have the script that is invoking ssh read the output stream. – William Pursell Jul 3 '18 at 14:35
  • @WilliamPursell If you can provide any sample code or something will be best for me. However I can not do scp from remote host to my local as scp needs public ip. – Shubham Kumar Rohit Jul 3 '18 at 14:36
  • 1
    What are you wanting to do with those pathnames? If you want to do something with them on the remote host, don't turn them into a string and send them back and forth, just run whatever you need to run on the remote host with find directly. – Kusalananda Jul 3 '18 at 14:46
2

Since you're comfortable using backticks and find to construct the array, you clearly aren't worried too much about serializing the data robustly (for example, whitespace in the output of find is going to be split into distinct element of the array, which may not be desired), so just do:

array=($( ssh username@11.22.333.44 sh -c "find . -name 'something*'"))

and build the array on the local host.

| improve this answer | |
  • 1
    I think ssh runs a shell anyway, so you don't need the sh -c – ilkkachu Jul 3 '18 at 14:40
  • sh -c "cmd" makes it easier to understand the quoting. ssh user@host cmd with "quoted string" runs cmd with "quoted" and "string" as separate, unquoted arguments. ssh user@host sh -c "cmd with 'quoted string'" runs the command as expected. ssh user@host "cmd with 'quoted string'" I believe is exactly the same, but IMO looks really weird. YMMV. Including sh -c is purely a style thing. – William Pursell Jul 3 '18 at 14:45
  • But I need to run change directory after ssh username@11.22.333.44 and need to find. – Shubham Kumar Rohit Jul 3 '18 at 14:47
  • You don't actually need to cd. You can just as easily do find /home/ubuntu/user/someFolder, or you can do sh -c 'cd ..; find . ...' – William Pursell Jul 3 '18 at 14:48
  • @WilliamPursell Worked! Really appreciated alot. – Shubham Kumar Rohit Jul 3 '18 at 14:52
0

From one of your comments, it sounds as if what you're intending to do is to create a list of pathnames of files that you'd like to transfer from the remote system to the local machine using scp. The issue with this is that you passing pathnames back and forth between the two systems which introduces the risk that filenames that includes whitespace characters may be mangled.

If you're looking for a way to transfer all the files that matches something* from somewhere under /home/ubuntu/user/someFolder on the remote machine, you may use rsync like this:

rsync -av --include='*/' --include='something*' --exclude='*' \
    --prune-empty-dirs \
    username@11.22.333.44:/home/ubuntu/user/someFolder/ ./target

This would find and transfer all files matching the pattern and the directory structure that they live in to the local machine under the path ./target.

The --include and --exclude patterns are applied from left to right and the first match is what matters:

  • --include='*/': Look into all subdirectories (empty directories, i.e. directories with no matching filenames, are not transferred due to --prune-empty-dirs).
  • --include='something*': The pattern that would match the things we're actually interested in.
  • --exclude='*': Ignore everything else.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.