I have written a bash script which starts a tcpip port and connects my device to my laptop for wireless debugging. This is the script at /bin/device_added.sh:
#!/bin/bash
adb shell ip -f inet addr show 2> /tmp/scripts.log
ip=$(adb shell ip -f inet addr show | egrep -o '192.*/' | sed 's/.$//')
adb tcpip 5555
adb connect $ip:5555
echo "USB device added at $(date)" >>/tmp/scripts.log
After configuring permissions with chmod, this works flawlessly on its own. But I want this script to be triggered whenever I plug in usb. I followed this answer to try to make this work. I created a 80-test.rules file at /etc/udev/rules.d and added this:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh"
and reloaded the rules file using: sudo udevadm control --reload
Whenever I plug in usb, the script gets run(the date gets logged in scripts.log) but my device doesn't get connected. What am I doing wrong? Why does the script work properly when I run it manually but not when it is triggered through udev?
Edit: On basis of #markp-fuso's and #Charles Duffy's comment, I tried logging the error to /tmp/scripts.log file. Turns out I am getting this error:
line 3: adb: command not found
Now the strange part is, I got this error earlier but I solved it by placing the shell command before the tcpip command(atleast that worked when I ran the script directly). How am I supposed to deal with this error now?
Update:
As #markp-fuso pointed out, the problem was that environment variables weren't accessible to that script. Hence I created a the adb's location as a variable in the script and then made that used that variable as throught. My script now:
#!/bin/bash
adb=/home/pranil/Android/Sdk/platform-tools/adb
$adb shell ip -f inet addr show 2> /tmp/scripts.log
ip=$($adb shell ip -f inet addr show | egrep -o '192.*/' | sed 's/.$//')
$adb tcpip 5555
$adb connect $ip:5555
echo "USB device added at $(date)" >>/tmp/scripts.log
This solved the error I was getting in logs but still the adb doesn't get connected at the required port. I have no idea where I am going wrong now. One more thing, after my script runs, the offline emulator is no longer shown as an output of abd devices command.
My work requires me to connect to several network drives over two different protocols, SMB and SSHFS. I got tired of typing in the commands to connect to them individually and being prompted for my password every time, so I wrote this script:
#!/bin/sh
# SSHFS shares
local_paths=("/Users/$USER/mnt/share_1" "/Users/$USER/mnt/share_2" "/Users/$USER/mnt/share_3")
remote_paths=("$USER#server.university.edu:/home/$USER" "$USER#server.university.edu:/some/path" "$USER#server.university.edu:/another/path")
echo "Enter password:"
read -s password
for i in "${!local_paths[#]}"; do
diskutil unmount ${local_paths[$i]}
echo "Mounting ${remote_paths[$i]} to ${local_paths[$i]}"
mkdir -p ${local_paths[$i]}
sshfs -o password_stdin ${remote_paths[$i]} ${local_paths[$i]} -o volname=$(basename ${local_paths[$i]}) <<< $password
echo
done
# SMB shares
local_paths=("/Users/$USER/mnt/share_4" "/Users/$USER/mnt/share_4")
remote_paths=("//$USER#different.server.university.edu:/home/$USER" "//$USER#different.server.university.edu:/some/path")
for i in "${!local_paths[#]}"; do
diskutil unmount ${local_paths[$i]}
echo "Mounting ${remote_paths[$i]} to ${local_paths[$i]}"
mkdir -p ${local_paths[$i]}
mount_smbfs ${remote_paths[$i]} ${local_paths[$i]}
done
It just loops through every path and disconnects/reconnects. It mostly works. After running it, I gain access to four of the five drives. For some reason, the last SSHFS in the array will mount, but I get a "permission denied" error message when I try to open the folder where it is mounted. If I re-order the array, it is always the last path that will error out like this. I have no such issue with the SMB shares.
Once this error happens, my computer is bugged out. Trying to forcibly unmount the share will just freeze my terminal. I lose all ability to access websites or do anything else that uses a network connection. I can't even restart the computer without holding down the power button for a hard reset.
Technical Specs:
Intel MacBook Pro
MacOS Big Sur
zsh, but I've tried this script in bash and sh with the same result.
Notes:
I tested this on a colleague's laptop and got the same results.
I am configuring a vs-code extension to send a cross-compiled binary to a raspberry pi.
Every step from compiling to copying the file runs fine.
ssh pi#123.123.123.123 "sudo mkdir /home/pi/remotePi/";
ssh pi#123.123.123.123 "sudo rm /home/pi/remotePi/blink_example";
ssh pi#123.123.123.123 "sudo chown pi /home/pi/remotePi/";
scp -l 8192 build/blink_example pi#123.123.123.123:/home/pi/remotePi/ &&
ssh pi#123.123.123.123 "echo "scp complete"" &&
ssh pi#123.123.123.123 "/home/pi/remotePi/blink_example"
Output:
mkdir: cannot create directory ‘/home/pi/remotePi/’: File exists
blink_example 100% 8692 277.3KB/s 00:00
scp complete
But when I try to run the file through an SSH command, the command stalls.
ssh pi#123.123.123.123 "home/pi/remotePi/blink_example"
It will eventually run, but it can take around 10 minutes. If I ssh into the pi and run the binary through an actual terminal, it runs immediately.
I have noticed that when it finally runs (using my extension), there are a lot of print statements (the test code just prints the read value from a pin). Does that mean it is running, but I'm maybe not getting the prints until there is enough to fill a packet?
So my question is, how can I run a binary on a remote machine and receive the terminal output in a timely manner?
Edit
I modified my program to not have any delays between print statements (essentially spamming stdout). This resulted in the ssh command ssh pi#123.123.123.123 "/home/pi/remotePi/blink_example" to return immediately and with all the prints.
This leads me to believe that there is a buffer that I need to fill (or limit the size of) before any terminal information is returned to the local device from the remote.
I figured out a solution, but it doesn't answer any of the questions about why spamming stdout will cause ssh to give a terminal output sooner.
In the original blink_example, I was using printf("pin 17: %d\n", digitalRead(17)); for displaying the value.
I converted the test application to c++ (not a terribly difficult task) and used std::cout << "pin 17: " << digitalRead(17) << std::endl;. Using this caused the terminal to give feedback right away.
My setup is complicated and I think I have a clear way ahead, but please let me know if you see a better way to accomplish my end state of using a terminal window over Xbee. My use case is that RPI #1 has internet connectivity, but RPI #2 does not, and I want to fully control and access RPI #2 via RPI #1 over Xbee.
I have x2 Raspberry Pi 3B+ and am using x2 Xbee Pro S3B modules to communicate between the RPIs over Xbee USB Development Shields. The Xbees show on the RPIs as /dev/ttyUSB0. I want to use the Xbees as a transportation layer to the RPIs, much like 802.11/15 or plain old ethernet would be used in a headless situation with bash. The Xbees are running at 115200 baud rate, and are named and setup via the X-CTU tool. I have no illusions of high speed data, but want to "see" RPI #2 terminal on RPI #1, the same as when SSH is accomplished with traditional transport layers.
I am able to use the Xbees in Transparent Mode, and send plain text with Screen, Minicom, "echo "text here" > /dev/ttyUSB0", and "cat < /dev/ttyUSB0". Despite the ability to pass messages, I want to use these plain text messages as bash input. For example, when I pass the command ls via any of the three methods listed from RPI 1, I want to have bash exectue "ls" on RPI 2, not just see it listed on the screen for RPI 2.
I've found several tools for Xbee, but don't want to wire up the GPIO pins and go that method; I want to use the Xbees as simple transport, nothing more. How do I pass text from /dev/ttyUSB0 to bash as a command, and see the results? Short of a more direct route, I'm considering using crontabs and an executable file that is erased and re-written to accomplish this task, but feel that is a last, very ineffective, method.
Is there some tool I am missing that does this already? Can I "screen" over a serial port as command line and serial I/O simultanously?
I found pyserial, which could allow for a TCP binding to the /dev/ttyUSB0 port, but am not sure if that is the right way to go or not. As of now, my code is as simple as
RPI #1:
echo "ls" > /dev/ttyUSB0
RPI #2:
cat < /dev/ttyUSB0
I was able to send and recieve commands from command line of a local (although remoted) XBee host to a remote (secondary, off net) Xbee host. I found the answer when I started looking at how serial devices could open a login terminal, and arrived at the getty tool. Here are my setup instructions for Transparent Mode use, I am still trying to get python-xbee and other tools to work to allow for the same concept, but via API mode. Note that the below instructions are a 95% solution, but should get the common user to a solid way ahead. I am not the original author of the steps below in their format, but found each step and combined them through various other Q&A forums to arrive at a solution:
First, acquire Digi Xbee X-CTU software (does not install on ARM devices such as Raspberry or Odroid):
XCTU:
Install from the following Digi.com link, but navigate to the corrresponding software FTP link:
https://www.digi.com/support/productdetail?pid=3352&type=drivers
Linux 64 Bit: ftp://ftp1.digi.com/support/utilities/40002881_R.run
Linux 32 Bit: ftp://ftp1.digi.com/support/utilities/40002880_R.run
Windows: ftp://ftp1.digi.com/support/utilities/40003026_T.exe
Mac: ftp://ftp1.digi.com/support/utilities/40003026_T.exe
Install X-CTU Via:
sudo wget ftp://ftp1.digi.com/support/utilities/40002880_R.run
sudo mv 40002881_R.run xctu_64bit.run
sudo chmod +x xctu_64bit.run
sudo ./xctu_64bit.run
Find X-Bee Device:
make sure Xbee is not plugged into a hub, power will be too little, recognizable via the below error, YMMV:
dmesg | grep ttyUSB0
and returning error: [ 228.800021] ftdi_sio ttyUSB0: failed to get modem status: -32
lsusb -v -d 0403:6001
sudo nano /boot/cmdline.txt
change the console tty device from AMA to USB, then for the kgdboc, which allows the remote end to watch the boot process, add/make match as appropriate
console=ttyUSB0,115200 kgdboc=ttyUSB0,115200
sudo nano /etc/inittab
make sure to uncomment (remove #) if present, change tty from AMA to USB
T0:23:respawn:/sbin/agetty -L ttyUSB0 115200 vt100
On Ubuntu x86 system, use X-CTU via
sudo ./XCTU.desktop
update firmware to the latest version
currently 8075 for the Pro S3B, then set baud rate to 115200 on each device
other xbees on in the vicinity can be updated by using a local xbee via X-CTU, then setting the api mode to “api mode with escapes”. Note that Transparent Mode should be used unless you have an indepth knowlege to make API mode work. I started with Transparent Mode to demonstrate the below works, but have since moved to API mode to gain the enhanced send-recieve control capabilities (pending a working version as of this writing).
do the same steps for all the devices that will be used on the network; once the local device is complete, other remote devices can be updated if visible (close enough).
Close out X-CTU and add the current user to the dialout group via:
sudo usermod -a -G dialout root
reboot then:
Setup Minicom Via:
sudo aptitude install minicom
minicom -s
serial port setup
a, set to /dev/ttyUSB0, then hit enter
e, set baud rate to 115200, then hit enter
hit enter again to close the window and arrive at the configuration page of minicom
select to save as dfl, followed by enter
then move to exit, and hit return
test connection to a locally connected device via
three plus symbols without hitting return
if it replies “ok” in a few seconds or less, all is well
OR Screen:
screen /dev/ttyUSB0
again, if you see a login prompt, you are connected. Note that screen is probably the best choice for most users; it has the inherent quality of ease of use (when compared to Minicom), handles low bandwidth connections with ease, and stays alive despite a disconnect from remote host. Ctl+a and then k will disconnect.
Install Coreutils to add more options than Minicom (Screen is also advisable):
sudo aptitude install coreutils && screen
stty -F /dev/ttyUSB0 -a
this will check serial port capabilities and settings
Communicate with your devices:
Note you interact with your network on a local machine with an X-Bee plugged in, or on a remote device you SSH over the internet, as long as it has an X-Bee attached. Also, note that the below settings to rc.local weren't keeping my settings after a reboot; this is a work in progress. I was setting them manually until I got automation worked out.
Also, I added rc.local to the RPI manually, the how-to for that is out there somewhere:
sudo systemctl stop serial-getty#ttyAMA0.service
sudo systemctl disable serial-getty#ttyAMA0.service
sudo systemctl enable serial-getty#ttyUSB0.service
sudo nano /etc/rc.local
add the below before exit 0
The stty line is twice because it has been noted that the first instance changes the reported baud rate to 9600, the second to 115200. If you are doing this manually, do a “stop” then re-do the start command to receive the prompt. This could be automated; I will update this post with a process monitor.
stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb raw
stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb raw
sudo systemctl start serial-getty#ttyUSB0.service
Then, use Minicom, Screen, or "cat" and "watch" to view messages sent. When using Minicom you will receive a login prompt via the above directions. As previously stated, I am still trying to get this working smoothly for API mode, but at least I know I have connectivity and can do basic command & control via the command line remotely with Transparent Mode, including running command line programs and commands. Transparent Mode does not offer any enhanced RF propagation correction techniques, hence my desire to get API mode working; RSSI values and error correction would be nice.
when I run this in terminal:
lsof -n -i4TCP:8081
I get this
node 10901 me 28u IPv6 0xbcad49 0t0 TCP *:sunproxyadmin (LISTEN)
foo 11957 me 15u IPv4 0xbcad49 0t0 TCP 127.0.0.1:61127->127.0.0.1:sunproxyadmin (CLOSE_WAIT)
What is this sunproxyadmin?
Per http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=8081, TCP port 8081 is the well known port for sunproxyadmin the same way 80 is the well known port for http. In this case, you have a node process that is listening on port 8081, but lsof is trying to be helpful and show the well known port for this. Under linux, this is defined in /etc/services; I would expect OS X is similar.
Edit 1: Note that per Apple Man Pages, passing -P
inhibits the conversion of port numbers to port names for network files.
Inhibiting the conversion may make lsof run a little faster. It
is also useful when port name lookup is not working properly.
This should cause lsof to not print out the confusing sunproxyadmin for something that just happens to use the port that Sun registered.
Edit 2: The second column in your response (e.g. 10901 in the first row, which is the one you want, and 11957 in the second row) should be the process ID. If you do ps aux | grep 10901 (or ps elf | grep [pid], as I can't remember which works right for OSX and don't have it handy) you should get something like:
apache 19783 0.0 0.2 251888 8580 ? S Oct07 0:00
/usr/sbin/httpd -DFOREGROUND
(or to make something up:
nodeuser 10901 0.0 0.2 251888 8580 ? S Oct07 0:00 node index.js
)
You can kill it with kill -9 10901 (or whatever the PID was) though you might find it comes back if it's running as a service or what.
This is useful enough to add to your bash profile:
function findbyport()
{
sudo lsof -P -iTCP:$1 -sTCP:LISTEN
}
Kill it, do in your terminal
sudo lsof -i :8081
from there get the PID number and then run
kill -9 <PID NUMBER>
You can check on FB documentation for more info
If you don't want to kill sunproxyadmin process, let try to start React native in different port with command:
react-native start --port your_port
Then open Dev settings (see how to open dev menu), and modify Debug server host & port for device to: your_local_ip:your_port
There is this MACAFEE antivirus running on my Mac. I am able to kill it(Even though I should not be killing it, I tried it, and looks like it never dies! Sudo has no power after all!).So after a lot of research I have tried this one.
Step 1 : Get the process' PID
sudo lsof -n -i4TCP:8081
Step 2 : Find the launchd endpoint
sudo launchctl list | grep
Step 3 : Remove mcafee
sudo launchctl remove com.mcafee.agent.macmn
If this one works for you pls say thanks to me and as well as https://fantashit.com/unable-to-perform-react-native-start/