This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 1 year ago.
I'm trying to run linux shell script on adb shell. It's giving errors!
Here is the whole story:
I wrote a simple bash script hello.sh :
#!/bin/bash
function hello
{
echo "hello world!"
}
hello
running it as ./hello.sh produces the o/p
hello world!
Now I pushed the file to android device using
adb push hello.sh /data/folder_name
then ran following command to enter in adb shell
adb shell
In adb shell fired following commands
cd /data/folder_name
chmod 755 hello.sh
sh hello.sh
This is what I get on adb shell :
# sh hello.sh
sh hello.sh
function: not found
hello world!
hello: not found
#
What's happening here!
Or is there some different way to write function for adb shell script
I searched but didn't get proper solution
Please help.
Not sure about adb, but 'function' is not standard syntax. It is available in many shells, but the standard way to define a function is:
hello() { echo hello world; }
When invoked as sh, bash enters posix mode and it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
The reserved word function is optional for bash, but I think is unknown to historical versions of sh.
Try to invoke the command as
bash /tmp/test.sh
You don't need to push the script to your phone - simply expand it in the shell itself like so and you save yourself time:
adb shell "$hello.sh"
Related
I am trying to run a shell script in my android board. It has android and I access via adb to the shell. After copying a simple .sh script, I have the following problems for running it.
Consecutive variables are not recognized. This does not work
PROJ_ON_SYS_PIN='1221'
echo $PROJ_ON_SYS_PIN> /sys/class/gpio/unexport
PROJ_ON_SYS_PIN_2='1222'
echo $PROJ_ON_SYS_PIN_2> /sys/class/gpio/unexport
But this alone works: echo 1221 > /sys/class/gpio/unexport
Enter seems strange behavior: Even refraining using variables this does not work, and is detected as a syntax error. I presume the return (skip line) in not working.
echo 1221> /sys/class/gpio/unexport
echo 1223> /sys/class/gpio/unexport
Is it related to the shell version?. Because I have been working with bash in linux quite a lot and never experienced this
I am trying to remove a file on my android using a single ADB command.
I understand you can just do adb shell and then remove the file using rm.
But I need it to be a one line execution.
I’ve tried:
adb rm-f /directory/file.txt
adb shell rm-f /directory/file.txt
Both don’t delete the file I want.
Delete file on android:
adb shell rm sdcard/download/file.ext
I noticed in your comments you are looking for one line execution since you're gonna be using Python. Well as an alternative you could use the subprocess module to write to stdout allowing you to execute as many commands of choice
for example
import subprocess
process = subprocess.Popen([r'adb', 'arg1', 'arg2'], stdout=subprocess.PIPE,stdin=
subprocess.PIPE) #start adb
process.stdin.write('shell \n') # Parse in input into the program
process.stdin.write('rm *\n') # Parse in second input
line=process.stdout.readline() # Read a line from stdout
It worked for me to run the following command:
adb shell rm -f -rR -v /sdcard/Documents/
This question already has an answer here:
windows batch script not execute next line after "adb shell"
(1 answer)
Closed 5 years ago.
I have a .bat file that runs script for testing an app and printing the log to file i have all the commands i tested them manually.
Problem:
after entering the command adb shell, the shell opens in the command prompt. I wrote the next commands that are entered in the shell with root#generic
the commands aren't going through and it just waits at that spot.
what do i have to type in front of the commands to make them appear
example of what i have
cd directory of sdk
adb
adb shell
am instrumentation ... (this is the command that won't go through once the shell is open.
any help appreciated I've tried a few things with no success
Just use the following line in your batch file:
adb shell am instrumentation
that will connect to the shell on the Android device and run the am command.
I have a couple of shell scripts stored in the /Scripts folder of my AppleScript application.
I can access them by setting my base path
set basePath to POSIX path of ((path to me as text)) & "Contents/Resources/Scripts/"
But I'm only able to run the script if I call the Terminal app
-- This works
tell application "Terminal"
set currentTab to do script (basePath & "install_key.sh")
end tell
-- This does not work
do shell script basePath & "install_key.sh"
The error on do shell script complains about not being able to find adb (Android Debug Bridge)
FWIW, here is the shell script in question (install_key.sh)
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
adb push $DIR"/key-dev.txt" /sdcard/ &&
adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
Problem
If I understand correctly, your main issue is that your script cannot detect and hold the presence of a specific command located on a system.
Solution
I believe the following code will be effective in helping you achieve your goal. This applescript allows you to find whether ADB is stored on a system and store it's path in a variable. You can add the variable to your path and export as others have suggested or have a look at the export process in Apple's TN2065.
If ADB is not found on a system then users can receive a prompt telling them what actions to take (if that aligns with your use-case or you could begin the install sequence for ADB). To test the behavior of the script you can simply change the adp to some other (fake) command that does not exist on your system. I've added the path to the dialog so that you can see the do shell is passing the contents of the which command into a variable.
try
set adbPath to do shell script "which adb"
on error errStr number errorNumber
-- If our own error number, warn about bad data.
if the errorNumber is not equal to 0 then
display dialog "ADB is not loaded onto system. Please load ADB and run this app again"
return 0 -- Return the default value (0).
else
-- An unknown error occurred. Resignal, so the caller
-- can handle it, or AppleScript can display the number.
error errStr number errorNumber
end if
end try
if length of adbPath > 0 then display dialog "ADB found continue processing..." & adbPath
The structure defined in the TN2065 above is essentially:
$ VAR=something; export VAR $ osascript -e 'do shell script "echo $VAR"' something
You might also want to try the administrator option when calling the shell script:
do shell script "command" user name "me" password "mypassword" with administrator privileges
The Technical Note TN2065: do shell script in AppleScript is the key reference for this kind of issues.
when you use just a command name instead of a complete path, the shell
uses a list of directories (known as your PATH) to try and find the
complete path to the command. For security and portability reasons, do
shell script ignores the configuration files that an interactive shell
would read, so you don’t get the customizations you would have in
Terminal.
First: find the full path of adb
you have to open a Terminal and issue the following command:
$ which adb
suppose the response is:
/Users/ronda/projects/android/sdk/platform-tools/adb
this means that the path of adb is:
/Users/ronda/projects/android/sdk/platform-tools
, now we have several way to address the problem, for example follow one of these two options:
Option1: Fix the AppleScript
do shell script "PATH=${PATH}:/Users/ronda/projects/android/sdk/platform-tools; export PATH; echo $PATH; " & basePath & "install_key.sh"
Option2: Fix the shell script
for example you could specify full path to the adb command in your .sh this way:
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
/Users/ronda/projects/android/sdk/platform-tools/adb push $DIR"/key-dev.txt" /sdcard/ &&
/Users/ronda/projects/android/sdk/platform-tools/adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
The simplest solution would be running the same bash configuration as your terminal application. The main difference is that Terminal uses an interactive bash and do shell script command doesn't. To run an interactive shell you can simply execute a new one with option -i (stands for interactive). When an interactive shell is opened the ~/.bashrc file is used, while non-interactive shells don't use this file.
do shell script "bash -i <<<" & quoted form of (basePath & "install_key.sh" as text)
if you don't like that you can simply execute the bashrc file or read the path variable and set it in a do shell script.
Does anyone know how to run commands from adb shell and remain in shell session?
What I`m trying to achieve is to set aliases in adb shell.
I have tried the following without success
adb shell <<< "ls"
After executing this command indeed remain in shell, but cannot receive output of any further command.
I have also tried the following:
adb shell <<EOF
ls
EOF
with the same result.
When you run:
adb shell ls
You are running this command currently outside of ADB.
First, you need to enter ADB:
adb shell
Once you enter ADB shell, you can continue to see output and input more commands.
ls
help
To exit ADB, simply type "exit" or hit "Ctrl + C"
expect solution
This will run the command, and leave you in an ADB shell automatically.
adb-cmd
#!/usr/bin/env expect
spawn adb shell
expect "#"
send [ concat [ join $argv " " ] ]
send "\r"
interact
Usage:
adb-cmd 'cd /data/data; ls'
Tested in Ubuntu 16.04 host, Android O guest.
There was a similar question answered in the comments here.
In short, run the following from your terminal:
stty raw -echo ; ( echo "ls" && cat ) | adb shell ; stty sane
Note: without the stty magic, the command is piped to adb and tab complete etc. is not recognized.
//you can use a nodejs script as below:
//let input='shell script here'
let input='cd /data/local/tmp\nchmod +x a.out\n./a.out\n'
p=run("adb.exe",args:'shell',cb:rs=>lg(rs)})
p.stdout.on("data",rs=>{
lg(rs)
setInterval(_=>process.exit(),2000);
})
p.stdin.write(input)
//+++++++++++++++++++++++++
function lg(...args){
console.log(...args);
}
function run(cmd,args,cb){
if(args) cmd= cmd+" "+args;
return require('child_process').exec(cmd,(er,stdout,stderr)=>{
if(er) return cb(stdout||stderr,false);
stdout=stdout==''?true:stdout;
cb(stdout,true)
});
}