linux - Connect to the right serial port in Unix
2014-04
Background
I'm trying to connect to a device using UART
though a micro-USB cable and GNU screen
from Ubuntu and OSX.
On both Ubuntu and OSX I can get the most recent serial connection with the following command, which I have run just after having connected my device and turned it on.
ls -t /dev/tty* | head -n 1
On Ubuntu I get (this is actually the output of ll
and -n 3
so I can see better what's shown)
crw-rw---- 1 root dialout 166, 0 Jan 29 10:51 /dev/ttyACM0
crw-rw-rw- 1 root tty 5, 0 Jan 29 10:14 /dev/tty
crw-rw---- 1 root dialout 4, 68 Jan 21 16:19 /dev/ttyS4
and the first item is correct (i.e. I can screen /dev/ttyACM0 115200
).
On Mac, instead, I get this
crw--w---- 1 atcold tty 16, 4 29 Jan 10:56 /dev/ttys004
crw-rw-rw- 1 root wheel 19, 44 29 Jan 10:56 /dev/tty.usbmodemfd121
crw--w---- 1 atcold tty 16, 6 28 Jan 16:21 /dev/ttys006
and the first item is wrong (I cannot connect to it) whereas the working one is the second one (and I had to turn off and turn on my device twice, since the first time there was not any /dev/tty.usbmodemfd121
at all).
Question
My question is easy. How can I access automatically the correct serial connection? I'm trying to avoid to give too many troubles to the final user trying to sort this problem out automatically.
Answer
This is my final script :)
read -p "Connect the switched off board, then press <Enter>" temp
ls /dev/tty* > /tmp/old_tty
read -p "Turn on the board and press <Enter>" temp
ls /dev/tty* > /tmp/new_tty
screen $(comm -13 /tmp/old_tty /tmp/new_tty) 115200
A solution could be to dectect the active serial connection before and after plugging the micro-usb, and then connect to the one present only after the micro-usb is plugged. This can be done for example with an sh script
#!/bin/sh
PATH_SUFFIX="/dev/tty"
read -p "Be sure the mini usb adapter is unplugged then press ENTER" temp
BEFORE=`ls -1 ${PATH_SUFFIX}* `
read -p "Now plug device and then press ENTER" temp
# sleep 2 seconds to be sure the filedevise is created
sleep 2
AFTER=`ls -1 ${PATH_SUFFIX}*`
OLD_IFS=$IFS
IFS='
'
for file in $AFTER ; do
if case ${BEFORE} in *"${file}"*) false;; *) true;; esac; then
FOUND=$file
fi
done
IFS=$OLD_IFS
#Now do whatever with FOUND device
echo $FOUND
You might want to look at setting up a udev rule to create a symlink with a specific name for this serial device.
Assuming you can identify the device by vendor or serial number.
This should help:
http://noctis.de/ramblings/linux/49-howto-fixed-name-for-a-udev-device.html
I have a two seperate files on my computer,
which execfile
/usr/local/bin/
/usr/bin/
so, i have two files with the same name in two different directories. How can I specify exactly which command to run?
Thanks.
you can specify the full path to the command when you run it type:
/usr/bin/execfile
or
/usr/local/bin/execfile
to run the exact file at that path
When trying to execute a command foo, foo is searched in the directories specified by the PATH environment variable, in the same order as they are specified. If you want to avoid this, type the full path to the executable.
Type this in a terminal:
echo $PATH
to see your actual PATH environment variable content.
For example, if you want to always execute first executables inside /bin, make sure /bin comes first inside $PATH. You can specify PATH in the .profile file in your home directory. So for the example above, edit the file and put this line at the end:
export PATH=/bin:$PATH
This will work only for your user. If you want to specify $PATH in a system-wide fashion (it will work for all users except for those who change it in their .profile), add the same line above in the file /etc/profile (you will need root privileges.)
Also remember that profile files are only parsed initially. This means that if you edit your personal .profile file, you will have to make your shell re-parse it. You can do this logging out and logging in again or otherwise typing:
source ~/.profile
For the system-wide change, type
source /etc/profile
This will make your current shell session re-parse the profile file. If you want your complete bootstrapped system to parse it again, I think you better restart your session.
Also remember that this may change if you use a shell other than bash.
You can find some interesting information inside the bash man page: http://linux.die.net/man/1/bash
See section "Command Execution".
also check for that if they both belongs to same file - like it may be link
ls -al /usr/bin
ls -al /usr/local/bin
and check whether they are linked together
if they are linked then u can execute any no-difference, else you have to specify full path
/usr/local/bin/execfile
/usr/bin/execfile
Write an alias in ~/.profile:
alias execfile='/usr/local/bin/execfile'
After the next login the right version will be chosen automatically. Start the other ones with the full path.