r send a text message with AppleScript in a function that includes the message and number as parameters - r

The question and answer at this link
Send a text message from R
use a function to create the AppleScript. I have copied it below
send_text = function(message){
system(paste('osascript -e \'tell application "Messages"\' -e \'send "', message,
'" to buddy "xxx-yyy-zzzz" of (service 1 whose service type is iMessage)\' -e \'end tell\''))
}
send_text("Hello world")
I'd like to modify the function so it can take both the message and the number, like this - send_text = function(number, message)
I can't figure out how the paste works to replace xxx-yyy-zzz with the variable number.

The paste function works by combining everything separated by commas into a single string. All you have to do is extract the "xxx-yyy-zzzz" from the sentence, replace it with number, and use commas.
send_text = function(message, number){
paste('osascript -e \'tell application "Messages"\' -e \'send "', message,
'" to buddy \"', number, '\" of (service 1 whose service type is iMessage)\' -e \'end tell\'')
}
send_text("Hello world", "555-888-0909")
#> [1] "osascript -e 'tell application \"Messages\"' -e 'send \" Hello world \" to buddy \" 555-888-0909 \" of (service 1 whose service type is iMessage)' -e 'end tell'"
Or alternatively you could use string interpolation from the glue package and insert the variable directly into the string with brackets.
send_text_2 <- function(message, number){
glue::glue(
'osascript -e \'tell application "Messages"\' -e \'send "{message}" to buddy "{number}" of (service 1 whose service type is iMessage)\' -e \'end tell\''
)
}
send_text_2("Hello world", "555-888-0909")
#> osascript -e 'tell application "Messages"' -e 'send "Hello world" to buddy "555-888-0909" of (service 1 whose service type is iMessage)' -e 'end tell'
Created on 2023-02-19 with reprex v2.0.2

Related

Confusion about the composition of the `cmd` parameter used in Deno.run()

I tried to use Deno as a replacement for shell script, but got stuck.
I attempted to use Deno/Typescript to carry out the equivalent job as this:
docker run \
-d \
-v pgdata:/var/lib/postgresql/data \
--name pg \
-e POSTGRES_PASSWORD=123456 \
--rm \
-p 5432:5432 \
postgres
ts code looks like this:
function runCmd(s: string[]): Deno.Process {
return Deno.run({ cmd: s, stdout: "piped", stderr: "piped" })
}
function runPg() {
const cmd = [
"docker",
`run -d -v ${VOLUME}:/var/lib/postgresql/data --name pg -e POSTGRES_PASSWORD=${PASSWORD} --rm -p 5432:5432 postgres`
];
return runCmd(cmd);
}
add execution bit to this ts file and run it in terminal:
after this, I tried
function runPg() {
const cmd = [
"docker",
"run",
`-d -v ${VOLUME}:/var/lib/postgresql/data --name pg -e POSTGRES_PASSWORD=${PASSWORD} --rm -p 5432:5432 postgres`
];
return runCmd(cmd);
}
move out subcommand run from command options.
I got this:
I guess that Deno.run doesn't simply concatenate the passed-in string of command particles, but I cannot find enough information on this subject in order to fix the issue.
I haven't gone through the rust source code on this API, but I thought it's better to ask for help before trying the hard way.
You need to specify each part of the command as a separate string in the cmd array:
function runPg() {
const cmd = [
"docker",
"run",
"-d",
"-v",
`${VOLUME}:/var/lib/postgresql/data`,
"--name",
"pg",
"-e",
`POSTGRES_PASSWORD=${PASSWORD}`,
"--rm",
"-p",
"5432:5432",
"postgres"
];
return runCmd(cmd);
}
This will send run as the first argument to docker instead of sending run -d … as the first argument.
You can also build your command as a single string and then use split(" ") as long as no arguments contain spaces.
a follow up on my trial-n-error journey on this top.
While reading a book about unix shell programming, it points out a way to help the shell differentiate the space in identifier and the space as delimiter. When one tries to cat a file named a b (there is a space in between), the command should be cat a\ b or, using quotes, cat 'a b'.
This gives me an idea why my command does not work in Deno. See, each item in the cmd string list is an identifier, when I mix up delimiter-space with identifiers, the command is interpreted in the wrong way.
For example.
If I'd like to cat a file named a b. In Deno.run, I need to use { cmd: ["cat", "a b"] }.
If I'd like to cat two files named a and b. In Deno.run, I need to use { cmd: ["cat", "a", "b"] }.
Just remember that space in a command particle counts as a part of that term.

Parameter value truncated from second word onwards in ksh

I am calling a function in commonfuncs to send email as below:
#!/usr/bin/ksh
. commonfuncs
emailsend 'test mail' 'body of the mail' 'abc.efg#domain.com'
the function is as below:
function emailsend
{
esubject=$1
etext=$2
etolist=$3
efromid="from.id#domain.com"
echo $etext >email.txt
cat email.txt | mailx -r $efromid -s $esubject $etolist
}
The email is sent fine. But the subject is send only as test instead of test mail. Tried with double quotes too but no use.
Try to wrap with double quotes parameters of the malix command:
cat email.txt | mailx -r "$efromid" -s "$esubject" "$etolist"
because the space character is a delimiter of the command line arguemnts.

How to correctly escape system calls from inside R

I have several shell commands that I want to run in in R.
I have tried system() but I have not find out how to do the right escaping even using shQuote.
# works OK
system('ls -a -l')
but how I execute a command like perl -e 'print "test\n"' or curl --data-urlencode query#biomart.xml http://biomart.org/biomart/martservice/results inside R?
update:
In the case of commands like the perl example I do not know how to do the escaping of quotes as it needs to be quoted as string but already use both types of quotes.
In the case of curl, the problem seems to be in the RESTful call to pass the xml with the # that works in the shell but not in the system() call
dat <-system('curl --data-urlencode query#biomart.xml http://biomart.org/biomart/martservice/results', intern=F)
Warning: Couldn't read data from file "query#biomart.xml", this makes an empty
Warning: POST.
The file is biomart.xml not query#biomart.xml
** Update2**
The xml file I am using for test is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Query>
<Query virtualSchemaName = "default" formatter = "TSV" header = "0" uniqueRows = "0" count = "" datasetConfigVersion = "0.6" >
<Dataset name = "hsapiens_gene_ensembl" interface = "default" >
<Filter name = "hgnc_symbol" value = "LDLR"/>
<Attribute name = "external_gene_id" />
</Dataset>
</Query>
Strings in R may be enclosed in either single (') or double (") quotes.
If you want to execute a command with both single and double quotes, such as:
perl -e 'print "test\n"'
then it is of little consequence which you choose for your R string - since one pair needs to be escaped either way.
Let's say you choose single quotes:
system('')
Then we need to escape the single quotes in the same way as for the newline character, with the escape character, \:
command <- 'perl -e \'print "test\n"\''
system(command)
It is also possible to encode Unicode characters in this way with \Unnnnnnnn or \unnnn. Alternatively with octal (\nnn), or hex (\xnnn).
Thus:
atSymbol <- '\u0040' # '\x040' '\100'
If the # in your curl command is causing the problem, encoding it like this should fix it.
In this example, in addition to escaping ', I had to escape \\ (with \\\\), \., \G, \K, but not \n
⌄ ⌄⌄ ⌄ ⌄ ⌄ ⌄ ⌄ ⌄
perl -0777 -pi -e ' s{ \\usage.*?\n\.\.\.\n} { ($r = $&) =~ s/\n//g; $r =~ s/\G.{0,79}(,|.$)\K/\n/g; $r }gse' filename.txt
system('perl -0777 -pi -e \' s{\\\\usage.*?\n\\.\\.\\.\n}{ ($r = $&) =~ s/\n//g; $r =~ s/\\G.{0,79}(,|.$)\\K/\n/g; $r }gse\' filename.txt')

How can I set a default value when incorrect/invalid input is entered in Unix?

i want to set the value of inputLineNumber to 20. I tried checking if no value is given by user by [[-z "$inputLineNumber"]] and then setting the value by inputLineNumber=20. The code gives this message ./t.sh: [-z: not found as message on the console. How to resolve this? Here's my full script as well.
#!/bin/sh
cat /dev/null>copy.txt
echo "Please enter the sentence you want to search:"
read "inputVar"
echo "Please enter the name of the file in which you want to search:"
read "inputFileName"
echo "Please enter the number of lines you want to copy:"
read "inputLineNumber"
[[-z "$inputLineNumber"]] || inputLineNumber=20
for N in `grep -n $inputVar $inputFileName | cut -d ":" -f1`
do
LIMIT=`expr $N + $inputLineNumber`
sed -n $N,${LIMIT}p $inputFileName >> copy.txt
echo "-----------------------" >> copy.txt
done
cat copy.txt
Changed the script after suggestion from #Kevin. Now the error message ./t.sh: syntax error at line 11: `$' unexpected
#!/bin/sh
truncate copy.txt
echo "Please enter the sentence you want to search:"
read inputVar
echo "Please enter the name of the file in which you want to search:"
read inputFileName
echo Please enter the number of lines you want to copy:
read inputLineNumber
[ -z "$inputLineNumber" ] || inputLineNumber=20
for N in $(grep -n $inputVar $inputFileName | cut -d ":" -f1)
do
LIMIT=$((N+inputLineNumber))
sed -n $N,${LIMIT}p $inputFileName >> copy.txt
echo "-----------------------" >> copy.txt
done
cat copy.txt
Try changing this line from:
[[-z "$inputLineNumber"]] || inputLineNumber=20
To this:
if [[ -z "$inputLineNumber" ]]; then
inputLineNumber=20
fi
Hope this helps.
Where to start...
You are running as /bin/sh but trying to use [[. [[ is a bash command that sh does not recognize. Either change the shebang to /bin/bash (preferred) or use [ instead.
You do not have a space between [[-z. That causes bash to read it as a command named [[-z, which clearly doesn't exist. You need [[ -z $inputLineNumber ]] (note the space at the end too). Quoting within [[ doesn't matter, but if you change to [ (see above), you will need to keep the quotes.
Your code says [[-z but your error says [-z. Pick one.
Use $(...) instead of `...`. The backticks are deprecated, and $() handles quoting appropriately.
You don't need to cat /dev/null >copy.txt, certainly not twice without writing to it in-between. Use truncate copy.txt or just plain >copy.txt.
You seem to have inconsistent quoting. Quote or escape (\x) anything with special characters (~, `, !, #, $, &, *, ^, (), [], \, <, >, ?, ', ", ;) or whitespace and any variable that could have whitespace. You don't need to quote string literals with no special characters (e.g. ":").
Instead of LIMIT=`expr...`, use limit=$((N+inputLineNumber)).

How to quote strings in file names in zsh (passing back to other scripts)

I have a script that has a string in a file name like so:
filename_with_spaces="a file with spaces"
echo test > "$filename_with_spaces"
test_expect_success "test1: filename with spaces" "
run cat \"$filename_with_spaces\"
run grep test \"$filename_with_spaces\"
"
test_expect_success is defined as:
test_expect_success () {
echo "expecting success: $1"
eval "$2"
}
and run is defined as:
#!/bin/zsh
# make nice filename removing special characters, replace space with _
filename=`echo $# | tr ' ' _ | tr -cd 'a-zA-Z0-9_.'`.run
echo "#!/bin/zsh" > $filename
print "$#" >> $filename
chmod +x $filename
./$filename
But when I run the toplevel script test_expect_success... I get cat_a_file_with_spaces.run with:
#!/bin/zsh
cat a file with spaces
The problem is the quotes around a file with spaces in cat_a_file_with_spaces.run is missing. How do you get Z shell to keep the correct quoting?
Thanks
Try
run cat ${(q)filename_with_spaces}
. It is what (q) modifier was written for. Same for run script:
echo -E ${(q)#} >> $filename
. And it is not bash, you don't need to put quotes around variables: unless you specify some option (don't remember which exactly)
command $var
always passes exactly one argument to command no matter what is in $var. To ensure that some zsh option will not alter the behavior, put
emulate -L zsh
at the top of every script.
Note that initial variant (run cat \"$filename_with_spaces\") is not a correct quoting: filename may contain any character except NULL and / used for separating directories. ${(q)} takes care about it.
Update: I would have written test_expect_success function in the following fashion:
function test_expect_success()
{
emulate -L zsh
echo "Expecting success: $1" ; shift
$#
}
Usage:
test_expect_success "Message" run cat $filename_with_spaces

Resources