简体   繁体   中英

no such file or directory: mount_smbfs {mount point} {local directory}

How can I get mount_smbfs to work on a Mac zsh terminal from within a loop?

The identical commands work when run one by one, but they throw an error when issued from within a loop: no such file or directory: mount_smbfs {mount point} {local directory} .

So, when I source something like this (the export commands actually live in their own script that gets sourced first):

export H_DIR="/mnt/${USER}"
export I_DIR="/mnt/I"
export DUM_HOST="dummy.host.ninja"

declare -A mounts
mounts[${H_DIR}]="//${USER}@${DUM_HOST}/${USER}"
mounts[${I_DIR}]="//${DUM_HOST}/I"
 
for dir mount_point in ${(kv)mounts}; do
 if [ ! -d $dir ]; then
  echo "Making $dir and intermediates."
  mkdir -p $dir
 #else
  #command="diskutil unmount $dir"  
  #echo "command: $command"
  #$command
 fi
 
 command="mount_smbfs $mount_point $dir"
 echo "command: $command"
 $command

 ls -alt $dir
done

I get something like this:

command: mount_smbfs //me@dummy.host.ninja/me /mnt/me
/Users/me/.zsh_setup/mount_all.zsh:24: no such file or directory: mount_smbfs ///me@dummy.host.ninja/me /mnt/me
total 0
drwxr-xr-x  3 me  staff  96 Dec 20 14:30 ..
drwxr-xr-x  2 me  staff  64 Dec 20 14:30 .
command: mount_smbfs //dummy.host.ninja/I /mnt/I
/Users/me/.zsh_setup/mount_all.zsh:24: no such file or directory: mount_smbfs ///dummy.host.ninja/I /mnt/I
total 0
drwxr-xr-x  3 me  staff  96 Dec 20 14:30 ..
drwxr-xr-x  2 me  staff  64 Dec 20 14:30 .

But, I can just paste the same command that was run in the loop, and it works.

me@my_mac ~ % mount_smbfs //me@dummy.host.ninja/me /mnt/me
Password for dummy.host.ninja: 
me@my_mac ~ %
me@my_mac ~ % ls -alt /mnt/me
total 1499808
drwxr-xr-x  3 me  staff         96 Dec 20 14:30 ..
drwx------  1 me  staff      16384 Dec 20 14:02 .
-rwx------  1 me  staff      10621 Dec 20 14:02 .bash_history
... A bunch more folders that live on the mounted host ...
me@my_mac ~ % 
me@my_mac ~ % 
me@my_mac ~ % mount_smbfs //dummy.host.ninja/I /mnt/I
me@my_mac ~ %   
me@my_mac ~ % ls -alt /mnt/I
total 960
drwx------  1 me  staff  16384 Dec 20 18:33 .snapshot
drwxr-xr-x  7 me  staff    224 Dec 20 14:30 ..
drwx------  1 me  staff  16384 Sep 21 11:22 .
... A bunch more folders that live on the mounted host ...
me@my_mac~ % 

For context:

me@my_mac ~ % ls -l /
total 9
drwxrwxr-x  21 root  admin   672 Dec 17 11:03 Applications
drwxr-xr-x  67 root  wheel  2144 Dec 16 10:03 Library
drwxr-xr-x@  9 root  wheel   288 Oct 12 23:06 System
drwxr-xr-x   6 root  admin   192 Dec 16 09:45 Users
drwxr-xr-x   3 root  wheel    96 Dec 20 12:38 Volumes
drwxr-xr-x@ 38 root  wheel  1216 Oct 12 23:06 bin
drwxr-xr-x   2 root  wheel    64 Oct 12 23:06 cores
dr-xr-xr-x   3 root  wheel  4507 Dec 20 12:38 dev
lrwxr-xr-x@  1 root  wheel    11 Oct 12 23:06 etc -> private/etc
lrwxr-xr-x   1 root  wheel    25 Dec 20 12:38 home -> /System/Volumes/Data/home
lrwxr-xr-x   1 root  wheel    26 Dec 20 12:38 mnt -> Users/me/mounts
... and so on ...
me@my_mac ~ % 
me@my_mac ~ % ls -l /Users/me/mounts
total 32
drwx------  1 me  staff  16384 Sep 21 11:22 I
drwxr-xr-x  3 me  staff     96 Dec 20 14:30 me
me@my_mac ~ % 

I need to enter my password once for the first mount, but not again because I use ssh keys. If I mount one manually to open the ssh key then run the for loop with other locations, that still won't work, so I don't think that's the issue.

As @GordonDavisson mentioned in the comments, the issue isn't with mount_smbfs but with how the command is parsed when assigned to a string variable. The best solution is to not do this, as seen here: Assigning command to a variable in Zsh . There are some suggestions for how to use a string variable as your actual command call, but I opted for just not doing it.

Making this minimum change works:

command="mount_smbfs $mount_point $dir"
echo "command: $command"
# Replace ...
# $command
# ... with the actual command:
mount_smbfs $mount_point $dir

Assigning the full command to a string was just for the convenience of echoing the command to the console before calling it, for logging and debugging. You can still do this, but it just won't be so tightly associated with the command itself, which isn't a real problem in this context where the command string variable is only used once right before calling the actual command. There are some suggestions in the linked post for how to get around this if you really want to use a string variable as your actual command call.

Also as mentioned in the comments and the linked post, it is perhaps best to wrap the command in a function. I tend to disagree in cases like this where it is a one-line command that is essentially function call itself. I'm not doing anything but calling it, no extra validation or anything. Wrapping it just adds an unnecessary layer of convolution. However, I haven't sought out a full explanation for why it might still be best practice.

That said, I will re-wrap the full script (minus the exports) back up into a set of functions as I originally did before troubleshooting and posting here. That's a good case for a function encapsulating a command or set of commands.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM