SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi,
I need to give some explanation before posting my question.
I am working on my second script.
What I am doing is searching out all the computers on my network.
1. I am creating directories in /home/server/ as mount points for the shared files from the other windows computers on my network.
2. I am adding cifs entries in fstab to automatically mount the shared files.
3. I am setting up shared printers.
Details
nmbscan prints a list of ipaddresses and related computer names.
Here is my script. I am not completely done.
Code:
#!/bin/sh
oldifs=$IFS #in case you need to change it back again later.
shopt -s extglob #Strips the rest unneeded info from buf
NMBSCAN=$(nmbscan -a) #Scan available ipaddresses and server names on a lan and put it into NMBSCAN
buf="${NMBSCAN#*server }" #buf strips "server" and only stores info after server.
SERVER="${buf%%+([$IFS])*}"
buf="${buf#*ip-address }"
IP="${buf%%+([$IFS])*}"
N=0
while test "$N" -le "${#IP[@]}"
do
#Setup mounted file system for shared files.
SMBZ=$(smbclient -L ${IP[$N]} -A /root/.smbpass) #To avoid running smbclient I put the results into a variable.
FILES=( $(echo "$SMBZ" | grep -v '.*\$' | awk '{if ($2 ~ /Disk/) print $1}') )
IFS='
'
for LIST in ${FILES[@]}; do
if [ ! -d /home/server/$numb/$FILES ]; then
echo "mkdir -p /home/server/${SERVER[$N]}/$LIST" #remove echo"" after testing
fi
if
#Add cfs to fstab
#need to add >> /etc/fstab to make official fi
echo "//${IP[$N]}/$LIST /home/server/${SERVER[$N]}/$LIST cifs credentials=/root/.smbpass,_netdev,uid=1000,gid=100 0 0"
done
##########Network printer setup for cups
PRINTERZ=( $(echo "$SMBZ" | awk '{if ($2 ~ /Printer/) print $1}') )
for PRINTZ in ${PRINTERZ[@]}; do #this is another way to do it.
echo "lpadmin -p $PRINTZ -v smb://$entry/$PRINTZ"
echo "lpadmin -d $PRINTZ"
done
N=$[N+1]
done
IFS=$oldifs #again, if necessary.
exit 0
The Problem
After running the script the USAGE for smbclient is printed. I am stumped. This my fifth version of this script, and I did not have problems with that part of the script in previous versions. I fiddled with it for days and compared to previous versions but still get the same results.
Unless there is a specific reason to run run sh, it is much better to run bash. Even if /bin/sh is a link to /bin/bash, bash will behave differently when called as sh; it will emulate sh behaviour which does not have many features of bash now in common usage.
Quote:
Originally Posted by okos
Code:
SMBZ=$(smbclient -L ${IP[$N]} -A /root/.smbpass) #To avoid running smbclient I put the results into a variable.
The comment is not accurate; smbclient is run by this statement. This is the statement that is causing the problem, probably because the arguments are not as intended. You can see what the arguments are by inserting an echo:
Code:
echo "DEBUG: smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ=$(smbclient -L ${IP[$N]} -A /root/.smbpass) #To avoid running smbclient I put the results into a variable.
If the arguments never contain whitespace you can use the following to provide information any time the command fails
Code:
cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ="$($cmd 2>1)"
rc=$?
if [[ $rc -ne 0 ]]; then
echo "ERROR: exit status $rc from $cmd. Output was:
$SMBZ"
exit 1
fi
The only variable passed to smbclient is ${IP[$N]} and $N looks OK so the problem is probably in ${IP[$N]}. ${IP[$N]} is an array reference but, inspecting the script, IP is not an array ... ?
Bash will raise an error on referencing an unset variable after processing this command. It's a useful feature.
Unless there is a specific reason to run run sh, it is much better to run bash.
Thanks didn't know the difference.
Quote:
Originally Posted by catkin
The only variable passed to smbclient is ${IP[$N]} and $N looks OK so the problem is probably in ${IP[$N]}. ${IP[$N]} is an array reference but, inspecting the script, IP is not an array ... ?
${IP[$N]} is an array with a list of available ipaddress. I tried
Quote:
echo "DEBUG: smbclient -L ${IP[$N]} -A /root/.smbpass"
It only printed
DEBUG: smbclient -L 192.168.1.19 -A /root/.smbpass
Quote:
Originally Posted by catkin
Bash will raise an error on referencing an unset variable after processing this command. It's a useful feature.
Code:
set -o nounset
Could you further explain this. Do I add this to the end of the script?
I will try your script for further debugging.
Further info
I even tried using the computer name instead of the ipaddress with the same results.
Additionally,
For some reason with this following code I don't have the same problem, just different problems. This code is not as simple as the code in my first post.
Code:
#!/bin/bash
SETARRAY=( $(nmbscan -a | grep -B1 'ip-address' | awk '{print $2}') )
for element in $(seq 0 $((${#SETARRAY[@]} - 1))) # ${#SETARRAY[@]} gives number of elements in the array.
do # seq 0 necessary to start the count at zero
#Separate server name which is given a even number
#+ from the ip address which is given an odd number
N=0
while test "$N" -lt "${#SETARRAY[@]}"
do
out=$(( $N % 2 ))
if [ $out -eq 0 ]
then
###########################make directory here for mount point.
##############${SETARRAY[$N]} will print the server name from nmbscan
# echo "$N is even number ${SETARRAY[$N]}"
SERVERNAME=${SETARRAY[$N]}
SMBZ=$(smbclient -L $SERVERNAME -A /home/root/.smbpass |grep -v '.*\$' | awk '{if ($2 ~ /Disk/) print $1}')
for numb1 in $(seq 0 $((${#SMBZ[@]} - 1))) # ${#SETARRAY[@]} gives number of elements in the array.
do # seq 0 necessary to start the count at zero
# if [ ! -d /home/server/$SERVERNAME/${SMBZ[$numb1]} ]; then
echo "mkdir -P /home/server/$SERVERNAME/${SMBZ[$numb1]}"
# fi
done
else
################${SETARRAY[$N]} will print the server ip address from nmbscan
echo "//${SETARRAY[$N]}/${SMBZ[$numb1]} /home/server/$SERVERNAME/${SMBZ[$numb1]} cifs credentials=/home/root/.smbpass,_netdev,uid=1000,gid=100 0 0" #add >>/etc/fstab
echo ""
PRINTERZ=$(smbclient -L ${SETARRAY[$N]} -A /home/dp/.smbpass | awk '{if ($2 ~ /Printer/) print $1}')
#Put the list of printers into an array starting at 0. Then setup the network printers in cups.
#This will work if one windows computer has several shared printers setup.
for numb2 in $(seq 0 $((${#PRINTERZ[@]} - 1))) # ${#PRINTERZ[@]} gives number of elements in the array.
do # seq 0 necessary to start the count at zero
echo "lpadmin -p ${PRINTERZ[$numb2]} -v smb://${SETARRAY[$N]}/${PRINTERZ[$numb2]}"
echo "lpadmin -d ${PRINTERZ[$numb2]}"
done
fi
N=$[N+1]
done
done
exit 0
When I ran your error script I get the following print.
Code:
ERROR: exit status 127 from smbclient -L -A /root/.smbpass. Output was:
How can I find what 127 means. The output was blank.
Also in your little script, could you explain rc=$?
Code:
cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ="$($cmd 2>1)"
rc=$?
if [[ $rc -ne 0 ]]; then
echo "ERROR: exit status $rc from $cmd. Output was:
$SMBZ"
exit 1
fi
When I ran your error script I get the following print.
Code:
ERROR: exit status 127 from smbclient -L -A /root/.smbpass. Output was:
How can I find what 127 means. The output was blank.
Also in your little script, could you explain rc=$?
Code:
cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ="$($cmd 2>1)"
rc=$?
if [[ $rc -ne 0 ]]; then
echo "ERROR: exit status $rc from $cmd. Output was:
$SMBZ"
exit 1
fi
Thanks
127 means "command not found". That's intriguing because clearly your script can usually find smbclient! Is there any chance that $PATH has been changed and does not include /usr/bin? It's good practice to give commands their full path, to avoid reliance on $PATH and to ensure that the intended command is used (there may be an alias or there may be a command of the same name in a directory listed earlier in $PATH). Thus you could try changing smbclient to /usr/bin/smbclient and se what happens.
The ERROR message shows that the IP address is missing from the command ... ?
Bash sets $? to the exit status of the last command run (the text refers to a pipeline but that includes a pipeline with only one command). rc=$? is used to preserve the value of the exit status set by $cmd for use in error reporting. If it were not recorded like this it would be lost when the [[ ]] on the next line was run and $? is set again. Why the name "rc"? It's short for "return code". "Exit status" and "return code" are synonymous in the bash documentation (in *n*x system calls they have different meanings but the usage is loose).
EDIT:
set -o nounset should appear before you want it to take effect, so probably that is at the start of the script.
I changed ownership of the script and .smbpass to root:root
I have the same credentials file with the same permissions in both /root and /home/dp
Here is my permissions.
root@bt:/home/dp/# ls -la /root/.smbpass
4.0K -r-------- 1 root root 35 2009-09-02 13:53 /root/.smbpass
root@bt:/home/dp/# ls -la .smbpass
4.0K -r-------- 1 root root 35 2009-07-14 16:15 .smbpass
When I run the script as root doing either
Code:
SMBZ=$(/usr/bin/smbclient -L ${SERVER[$N]} -A /home/dp/.smbpass)
It works without a problem.
Code:
SMBZ=$(/usr/bin/smbclient -L ${SERVER[$N]} -A /root/.smbpass)
I get the same USAGE error.
This just makes no sense.
I also setup both root and my user name dp with smbpasswd.
I edited the root file for the root password. Still no success.
Please run the sript with the following in and post the output so we can see the smbclient command that is causing the problem.
Code:
cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ="$($cmd 2>1)"
rc=$?
if [[ $rc -ne 0 ]]; then
echo "ERROR: exit status $rc from $cmd. Output was:
$SMBZ"
exit 1
fi
You could also try changing -A /root/.smbpass to -A <a non-existent file> to see what error message that generates
Please run the sript with the following in and post the output so we can see the smbclient command that is causing the problem.
Code:
cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
SMBZ="$($cmd 2>1)"
rc=$?
if [[ $rc -ne 0 ]]; then
echo "ERROR: exit status $rc from $cmd. Output was:
$SMBZ"
exit 1
fi
output is as so:
Code:
ERROR: exit status 127 from smbclient -L -A /root/.smbpass. Output was:
BTW Where do you suggest I put the credentials file? /root or /etc or /etc/samba ????
Quote:
You could also try changing -A /root/.smbpass to -A <a non-existent file> to see what error message that generates
Same error except smb asks for root password. The whole point of the credentials file is to avoid the prompt for the password.
ERROR: exit status 127 from smbclient -L -A /root/.smbpass. Output was:
This shows that the problem is in the script; ${IP[$N]} is empty as shown by no IP address after the -L. Are you still using this code
Code:
NMBSCAN=$(nmbscan -a) #Scan available ipaddresses and server names on a lan and put it into NMBSCAN
buf="${NMBSCAN#*server }" #buf strips "server" and only stores info after server.
SERVER="${buf%%+([$IFS])*}"
buf="${buf#*ip-address }"
IP="${buf%%+([$IFS])*}"
N=0
while test "$N" -le "${#IP[@]}"
do
...
If so then $IP is not an array and I do not understand how ${IP[$N]} can ever work.
How about posting your whole script so we can suggest why it isn't working or suggest some debugging statements to get a handle on what's going wrong?
Quote:
Originally Posted by okos
BTW Where do you suggest I put the credentials file? /root or /etc or /etc/samba ????
Same error except smb asks for root password. The whole point of the credentials file is to avoid the prompt for the password.
Doesn't matter as long as it's readable only by root. The advantage of putting it under /root is that the directory itself can also be made readable (and searchable) only by root.
It prints the same as root. Ips on the lan and computer names on the LAN
Quote:
dp@bt:/home/dp/Desktop/scripts$ nmbscan -a
nmbscan version 1.2.5 - bt - Fri Sep 4 14:08:19 PDT 2009
domain MSHOME
master-browser LEN 192.168.1.19 -
server LEN
ip-address 192.168.1.19
mac-address ***********
server-software Windows 2000 LAN Manager
operating-system Windows 5.1
It prints the same as root. Ips on the lan and computer names on the LAN
OK, so that's not the problem. Would you like to respond to my post so we can see the current version of your script and investigate why ${IP[$N]} is not set, giving rise to the usage message from smbclinet?
Here is the latest version of my script.
I moved the credentials to /etc I thought that would be more appropriate.
I echoed ${IP[$N]} and it definitely prints an ipaddress.
Code:
#!/bin/bash
#set -o nounset
echo "This script will search out shared files and printers on a network."
echo " "
echo "The mountpoint for shared files will be in /home/server/"
echo "An entry will be added to fstab to mount the shared files using cfs"
echo " "
echo "Shared printers will be added to cups via lpadmin. Cups will be given the same name as the shared printers."
echo "Do you wish to procede Y or N" ; read X
case $X in
y|Y|Yes|YES)
;;
*)
exit 0
;;
esac
oldifs=$IFS #in case you need to change it back again later.
shopt -s extglob #Strips the rest unneeded info from buf
NMBSCAN=$(/usr/bin/nmbscan -a) #Scan available ipaddresses and server names on a lan and put it into NMBSCAN
buf="${NMBSCAN#*server }" #buf strips "server" and only stores info after server.
SERVER="${buf%%+([$IFS])*}"
buf="${buf#*ip-address }"
IP="${buf%%+([$IFS])*}"
N=0
while test "$N" -le "${#IP[@]}"
do
#Setup mounted file system for shared files.
#cmd="smbclient -L ${IP[$N]} -A /root/.smbpass"
#SMBZ="$($cmd 2>1)"
#rc=$?
#if [[ $rc -ne 0 ]]; then
# echo "ERROR: exit status $rc from $cmd. Output was:
#$SMBZ"
# exit 1
#fi
echo "Print ip address here ${IP[$N]}"
SMBZ=$(/usr/bin/smbclient -L ${IP[$N]} -A /etc/.smbpass) #To avoid running smbclient too many times I put the results into a variable.
FILES=( $(echo "$SMBZ" | grep -v '.*\$' | awk '{if ($2 ~ /Disk/) print $1}') )
IFS='
'
for LIST in ${FILES[@]}; do
if [ ! -d /home/server/$numb/$FILES ]; then
echo "mkdir -p /home/server/${SERVER[$N]}/$LIST" #remove echo"" after testing
fi
if [ "$(cat /etc/fstab | grep '${SERVER[$N]}/$LIST')" != "${SERVER[$N]}/$LIST" ] ; then
#Add cfs to fstab
#need to add >> /etc/fstab to make official fi
echo "//${IP[$N]}/$LIST /home/server/${SERVER[$N]}/$LIST cifs credentials=/etc/.smbpass,_netdev,uid=1000,gid=100 0 0"
fi
done
##########Network printer setup for cups
PRINTERZ=( $(echo "$SMBZ" | awk '{if ($2 ~ /Printer/) print $1}') )
for PRINTZ in ${PRINTERZ[@]}; do #this is another way to do it.
echo "lpadmin -p $PRINTZ -v smb://${SERVER[$N]}/$PRINTZ"
echo "lpadmin -d $PRINTZ"
done
N=$[N+1]
done
IFS=$oldifs #again, if necessary.
exit 0
When I uncomment your error code it still prints the same.
Here is the output for my script.
Code:
root@bt:/home/dp/Desktop/scripts# ./2netscript.sh
This script will search out shared files and printers on a network.
The mountpoint for shared files will be in /home/server/
An entry will be added to fstab to mount the shared files using cfs
Shared printers will be added to cups via lpadmin. Cups will be given the same name as the shared printers.
Do you wish to procede Y or N
y
Print ip address here 192.168.1.19
Domain=[LEN] OS=[Windows 5.1] Server=[Windows 2000 LAN Manager]
Domain=[LEN] OS=[Windows 5.1] Server=[Windows 2000 LAN Manager]
mkdir -p /home/server/LEN/SharedDocs
//192.168.1.19/SharedDocs /home/server/LEN/SharedDocs cifs credentials=/etc/.smbpass,_netdev,uid=1000,gid=100 0 0
mkdir -p /home/server/MOM/Fdrive
//192.168.1.19/Fdrive /home/server/LEN/Fdrive cifs credentials=/etc/.smbpass,_netdev,uid=1000,gid=100 0 0
lpadmin -p HPOffice -v smb://LEN/HPOffice
lpadmin -d HPOffice
lpadmin -p hpphotos -v smb://LEN/hpphotos
lpadmin -d hpphotos
Print ip address here
Usage: smbclient [-?|--help] [--usage] [-R|--name-resolve NAME-RESOLVE-ORDER]
[-M|--message HOST] [-I|--ip-address IP] [-E|--stderr] [-L|--list HOST]
[-t|--terminal CODE] [-m|--max-protocol LEVEL] [-T|--tar <c|x>IXFqgbNan]
[-D|--directory DIR] [-c|--command STRING] [-b|--send-buffer BYTES]
[-p|--port PORT] [-g|--grepable] [-B|--browse]
[-d|--debuglevel DEBUGLEVEL] [-s|--configfile CONFIGFILE]
[-l|--log-basename LOGFILEBASE] [-V|--version]
[-O|--socket-options SOCKETOPTIONS] [-n|--netbiosname NETBIOSNAME]
[-W|--workgroup WORKGROUP] [-i|--scope SCOPE] [-U|--user USERNAME]
[-N|--no-pass] [-k|--kerberos] [-A|--authentication-file FILE]
[-S|--signing on|off|required] [-P|--machine-pass] [-e|--encrypt]
service <password>
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.