I do have several shell scripts whom are get activate not really behind each other.
But I want to stay in the same terminal window.
To simplify the problem, lets say that as example
first script. - cd to the working directory
second. - do some things and get files from that directory
third. - dome more thing on the newly files/folders in that directory.
fourth. - ....
How can I let script 2 and 3 ( all the script thus ) run in that very same directory and window that is opened during script 1?
F.e how can I avoid using the full path to that folder for every file.
EDIT: After adayzdone's answer I realize that I forgot to mention that I need also administrator privileges for one of the scripts
EDIT2: For now I use this
tell application "Terminal"
set newTab to do script
set current settings of newTab to settings set "Grass"
do script "bin/sh/ echo 'xx' | su;" in newTab
do script "cd " & quoted form of realParentPath in newTab
do script shellscript1 in newTab
do script shellscript..n in newTab
activate
end tell
but still no dice with the privileges.
try:
tell application "Terminal"
do script "cd ~/" in window 1
do script "ls -a" in window 1
end tell
OR
property usr : "username"
property pswd : "password"
set xxx to do shell script "cd ~/ ; ls -a " user name usr password pswd with administrator privileges
Related
Is there a way to write a "to do script" with administrator privileges like you can with a "do shell script" ? I have a script that I am writing that opens a terminal window and gets the size of another user account but I get permission denied errors. I can easily solve this by entering sudo before the command but I don't want to enter a password in the terminal window. I want to be prompted with a dialog so I can enter a password just like I would get if I used a "do shell script"
This is part of my script that I have:
tell application "Terminal"
activate
do script "sudo du -sh /Users/example"
end tell
I know that you can solve this also like this:
do shell script "du -sh /Users/example" with administrator privileges
but doing it like this opens a terminal window but does not start the command.
You can do it without involving Terminal.app at all
set userSize to do shell script "du -sh /Users/example | awk '{print $1}'" with administrator privileges
The awk command strips the size part from the result.
Your second option is correct, but it should not be used with a tell "Terminal" block at all.
With the script bellow (only the 2 lines), Terminal will not be open and the only window will be the one asking your admin password.
set UserSize to do shell script "du -sh /Users/test" with administrator privileges
display dialog UserSize
I have an AppleScript saved as an application. When first run, it asks the user if they want to move it to the Applications folder. What I would like to be able to do is, after it's been moved, have the script quit itself and then reopen.
Obviously I can't say
tell me to quit
tell me to activate
...because it would stop running after the quit command.
Any suggestions?
Just run the script from inside the script, and make sure to terminate the current running of it with a return (can skip the actual return command if it's the last line of the script
-- do stuff
display dialog "Here I am again"
-- set alias to the script
-- run the script
set myScript to path to me
run script myScript
-- end current iteration
return
You can break out of this script by canceling the dialog, but you'll probably want to set a condition to check whether to run the script again.
Here's how I'd do this. Basically, You check if the application is running from the Applications folder. If it isn't, move it there, open another instance, and quit. Seems to work flawlessly. The activate in the beginning is because it seems that the application doesn't always move itself to the foreground:
--incase the application doesn't do this automagically
activate
set my_path to POSIX path of (path to me)
if my_path does not start with "/Applications/" then
set new_path to "/Applications/" & quoted form of (my name & ".app")
--"mv" wont move the application into the new location if it exists
try
do shell script "rm -rf " & new_path
end try
do shell script "mv -f " & quoted form of my_path & " " & new_path
do shell script "open -n " & new_path & " &> /dev/null &"
quit
end if
What I am doing.
First I enabled at by running the following command in Terminal (this only has to be done once)
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
then I have the following script
display dialog "running"
set mypath to POSIX path of (path to me)
set lun to open for access POSIX file "/tmp/springboard" with write permission
write "open " & mypath & linefeed to lun
close access lun
do shell script "at -f /tmp/springboard +1 minute"
quit
I'm trying to write an automator service to fire up virtualhost.sh in a terminal.
Using the Services context menu the dialog opens to ask for the name of virtual host, then runs an applescript to launch terminal and pass in the input text.
What I want is to pass in my username and password to admin privileges so that I don't need to pass it in the terminal with sudo.
This can be done with do shell script but that executes a bin/sh and the virtualhost.sh is a bash script so I get the error bin/sh: virtualhost.sh command not found
Alternately I can use do script with command but this doesn't allow me to pass in the user name and password.
My code looks like so:
on run {input, parameters}
set vhost to "virtualhost.sh " & input
tell application "Terminal"
activate
do shell script vhost user name "user" password "pass" with
administrator privileges
end tell
end run
This produces the bin/sh error previously mentioned.
With do script with command
on run {input, parameters}
set vhost to "virtualhost.sh " & input
tell application "Terminal"
activate
do script with command vhost user name "user" password "pass" with
administrator privileges
end tell
end run
This produces an escaping error: Expected end of line, etc. but found property.
Is there a way to do this correctly?
Not specifically familiar with AppleScript Studio, but you can do it in plain old AppleScript (which appears to have the same issue) if you provide a full path to virtualhost.sh. (Also, Terminal is not required with "do shell script".) Example:
set vhost to "/usr/local/bin/virtualhost.sh " & input
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
You can also extend $PATH (which is by default /usr/bin:/bin:/usr/sbin:/sbin with "do shell script") to include the path to virtualhost.sh, e.g.:
set vhost to "{ PATH=$PATH:/usr/local/bin; virtualhost.sh " & input & "; }"
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
If you want a relative path, you can put virtualhost.sh inside the script application or bundle (e.g. in Contents/Resources), either in Terminal or by control-clicking and choosing "Show Package Contents". Then use "path to me":
set vhostPath to "'" & POSIX path of (path to me) & ¬
"/Contents/Resources/virtualhost.sh" & "'"
set vhost to vhostPath & space & input
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
Per the comment on my other answer, I'm posting a secondary answer more in the spirit of that there's a will, there's a way, but it's a different, more dangerous approach. However, it's the only solution I can think of to this particular requirement (to get the interactivity of Terminal, but without having to prompt for an administrator password while running a script as administrator).
This solution runs Terminal as root, which is what do shell script "command" with administrator privileges does. This is dangerous because you have an open Terminal window with root access, so carefully weigh benefits against potential consequences of, say, opening a new Terminal window and being at the Bash prompt as root.
For this reason, the Terminal instance that is opened is killed upon completion of the script; if the "kill" command is removed, be aware you'll get multiple instances of Terminal, rather than multiple windows within the same instance.
No idea if this works in AppleScript Studio (it works in AppleScript Editor), but I can't think of any reason why it wouldn't.
set input to "some_input"
set vhost to "/usr/local/bin/virtualhost.sh " & input
set kill to ¬
"terminal_pid=$(</tmp/terminal_pid); rm /tmp/terminal_pid; kill $terminal_pid"
-- launch Terminal as root, and save its process ID in /tmp/terminal_pid
tell application "Finder" to set beforeProcesses to processes
do shell script ¬
"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal " & ¬
"&> /dev/null & echo $! > /tmp/terminal_pid" user name "user" password ¬
"pass" with administrator privileges
-- wait until the new Terminal is confirmed to be running
tell application "Finder"
repeat while (processes is equal to beforeProcesses)
do shell script "sleep 0.5"
end repeat
end tell
-- Perform script in root Terminal window that we just opened,
-- and kill Terminal when done to prevent open root prompt
-- and multiple processes.
tell application "Terminal"
activate
do script vhost & "; " & kill
end tell
-- optional: wait until Terminal is gone before continuing
do shell script "while [[ ( -f /tmp/terminal_pid ) " & ¬
"&& ( \"$(ps -p $(</tmp/terminal_pid) -o%cpu='')\" ) ]]; do sleep 0.5; done"
How do I use the terminal to open another terminal window but with a path I specify?
I am using automator to load my work stuff when I get to work, but I need to know how to do this:
Open Terminal and Type:
• cd Work/Company/Project/
• script/server
And then new tab in that terminal window and cd to the same folder.
This opens a new terminal window from a command prompt on Mac OSX , executes "cd /" and then keeps the window on top:
osascript -e 'tell application "terminal"' -e 'do script "cd /"' -e 'end tell'
You can put this into a script like this:
#!/bin/sh
osascript -e 'tell application "terminal"' -e "do script \"cd $1\"" -e 'end tell'
Hope this helps.
Use an applescript to do this.
e.g. Open Terminal Here
You can write a shell script to cd to that directory
So write a script that executes something like cd /user/music or something like that, save it as myscript.sh and run it using chmod +x myscript.sh.
This resource from the OS X developer network is pretty helpful
The two scripts below together handle the common scenarios:
1) If Terminal is already running, open a new terminal window and run the 'cd mydir' there
2) If terminal is not already running, use the initial window that Terminal spawns (window 0), rather than annoyingly launching a second window
NOTE: what's not quite perfect is if Terminal has several windows open, all of them will be brought to the front, overlapping any other apps. A solution to raising only the last terminal window to the front appears to require the black magic of AppleScriptObjC - references below:
https://apple.stackexchange.com/questions/39204/script-to-raise-a-single-window-to-the-front
http://tom.scogland.com/blog/2013/06/08/mac-raise-window-by-title/
Script 1 - open a text editor and save as:
/usr/local/bin/terminal-here.sh
#!/bin/sh
osascript `dirname $0`/terminal-here.scpt $1 > /dev/null 2> /dev/null
Script 2 - open 'AppleScript Editor', paste contents below and save as:
/usr/local/bin/terminal-here.scpt
# AppleScript to cd (change directory) to a path passed as an argument
# If Terminal.app is running, the script will open a new window and cd to the path
# If Terminal.app is NOT running, we'll use the window that Terminal opens automatically on launch
# Run script with passed arguments (if any)
on run argv
if (count of argv) > 0 then
# There was an argument passed so consider it to be the path
set mypath to item 1 of argv
else
# Since no argument was passed, default to the home directory
set mypath to "~"
end if
tell application "System Events"
if (count (processes whose bundle identifier is "com.apple.Terminal")) is 0 then
# Terminal isn't running so we'll make sure to run the 'cd' in Terminal's first window (0)
tell application "/Applications/Utilities/Terminal.app"
# Turn off echo, run the 'cd', clear screen, empty the scrollback, re-enable echo
do script "stty -echo; cd " & (mypath as text) & ";clear; printf \"\\e[3J\"; stty echo" in window 0
activate last window
end tell
else
# Terminal is already running so we'll let it open a new window for our 'cd' command
tell application "/Applications/Utilities/Terminal.app"
# Turn off echo, run the 'cd', clear screen, empty the scrollback, re-enable echo
do script "stty -echo; cd " & (mypath as text) & ";clear; printf \"\\e[3J\"; stty echo"
activate last window
end tell
end if
end tell
end run
I've been trying to figure out how to run a bash command in a new Max OS X Terminal.app window. As, an example, here's how I would run my command in a new bash process:
bash -c "my command here"
But this reuses the existing terminal window instead of creating a new one. I want something like:
Terminal.app -c "my command here"
But of course this doesn't work. I am aware of the "open -a Terminal.app" command, but I don't see how to forward arguments to the terminal, or even if I did what arguments to use.
one way I can think to do it off the top of my head is to create a .command file and run it like so:
echo echo hello > sayhi.command; chmod +x sayhi.command; open sayhi.command
or use applescript:
osascript -e 'tell application "Terminal" to do script "echo hello"'
although you'll either have to escape a lot of double quotes or not be able to use single quotes
Partial solution:
Put the things you want done in a shell-script, like so
#!/bin/bash
ls
echo "yey!"
And don't forget to 'chmod +x file' to make it executable. Then you can
open -a Terminal.app scriptfile
and it will run in a new window. Add 'bash' at the end of the script to keep the new session from exiting. (Although you might have to figure out how to load the users rc-files and stuff..)
I've been trying to do this for a while. Here is a script that changes to the same working directory, runs the command, and closes the terminal window.
#!/bin/sh
osascript <<END
tell application "Terminal"
do script "cd \"`pwd`\";$1;exit"
end tell
END
In case anyone cares, here's an equivalent for iTerm:
#!/bin/sh
osascript <<END
tell application "iTerm"
tell the first terminal
launch session "Default Session"
tell the last session
write text "cd \"`pwd`\";$1;exit"
end tell
end tell
end tell
END
Here's yet another take on it (also using AppleScript):
function newincmd() {
declare args
# escape single & double quotes
args="${#//\'/\'}"
args="${args//\"/\\\"}"
printf "%s" "${args}" | /usr/bin/pbcopy
#printf "%q" "${args}" | /usr/bin/pbcopy
/usr/bin/open -a Terminal
/usr/bin/osascript -e 'tell application "Terminal" to do script with command "/usr/bin/clear; eval \"$(/usr/bin/pbpaste)\""'
return 0
}
newincmd ls
newincmd echo "hello \" world"
newincmd echo $'hello \' world'
see: codesnippets.joyent.com/posts/show/1516
Here's my awesome script, it creates a new terminal window if needed and switches to the directory Finder is in if Finder is frontmost. It has all the machinery you need to run commands.
on run
-- Figure out if we want to do the cd (doIt)
-- Figure out what the path is and quote it (myPath)
try
tell application "Finder" to set doIt to frontmost
set myPath to finder_path()
if myPath is equal to "" then
set doIt to false
else
set myPath to quote_for_bash(myPath)
end if
on error
set doIt to false
end try
-- Figure out if we need to open a window
-- If Terminal was not running, one will be opened automatically
tell application "System Events" to set isRunning to (exists process "Terminal")
tell application "Terminal"
-- Open a new window
if isRunning then do script ""
activate
-- cd to the path
if doIt then
-- We need to delay, terminal ignores the second do script otherwise
delay 0.3
do script " cd " & myPath in front window
end if
end tell
end run
on finder_path()
try
tell application "Finder" to set the source_folder to (folder of the front window) as alias
set thePath to (POSIX path of the source_folder as string)
on error -- no open folder windows
set thePath to ""
end try
return thePath
end finder_path
-- This simply quotes all occurrences of ' and puts the whole thing between 's
on quote_for_bash(theString)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to "'"
set the parsedList to every text item of theString
set AppleScript's text item delimiters to "'\\''"
set theString to the parsedList as string
set AppleScript's text item delimiters to oldDelims
return "'" & theString & "'"
end quote_for_bash
I made a function version of Oscar's answer, this one also copies the environment and changes to the appropriate directory
function new_window {
TMP_FILE=$(mktemp "/tmp/command.XXXXXX")
echo "#!/usr/bin/env bash" > $TMP_FILE
# Copy over environment (including functions), but filter out readonly stuff
set | grep -v "\(BASH_VERSINFO\|EUID\|PPID\|SHELLOPTS\|UID\)" >> $TMP_FILE
# Copy over exported envrionment
export -p >> $TMP_FILE
# Change to directory
echo "cd $(pwd)" >> $TMP_FILE
# Copy over target command line
echo "$#" >> $TMP_FILE
chmod +x "$TMP_FILE"
open -b com.apple.terminal "$TMP_FILE"
sleep .1 # Wait for terminal to start
rm "$TMP_FILE"
}
You can use it like this:
new_window my command here
or
new_window ssh example.com
A colleague asked me how to open A LOT of ssh sessions at once. I used cobbal's answer to write this script:
tmpdir=$( mktemp -d )
trap '$DEBUG rm -rf $tmpdir ' EXIT
index=1
{
cat <<COMMANDS
ssh user1#host1
ssh user2#host2
COMMANDS
} | while read command
do
COMMAND_FILE=$tmpdir/$index.command
index=$(( index + 1 ))
echo $command > $COMMAND_FILE
chmod +x $COMMAND_FILE
open $COMMAND_FILE
done
sleep 60
By updating the list of commands ( they don't have to be ssh invocations ), you will get an additional open window for every command executed. The sleep 60 at the end is there to keep the .command files around while they are being executed. Otherwise, the shell completes too quickly, executing the trap to delete the temp directory ( created by mktemp ) before the launched sessions have an opportunity to read the files.
Another option that needs to be here is "ttab"
https://www.npmjs.com/package/ttab
Install
npm install ttab -g
Usage : Open another tab and run ls
ttab ls
Usage 2 : Open new tab, with Green BG, with title "hi", in directory ~/dev, and run code .
ttab -s Grass -t hi -d '~/dev' code .
I call this script trun. I suggest putting it in a directory in your executable path. Make sure it is executable like this:
chmod +x ~/bin/trun
Then you can run commands in a new window by just adding trun before them, like this:
trun tail -f /var/log/system.log
Here's the script. It does some fancy things like pass your arguments, change the title bar, clear the screen to remove shell startup clutter, remove its file when its done. By using a unique file for each new window it can be used to create many windows at the same time.
#!/bin/bash
# make this file executable with chmod +x trun
# create a unique file in /tmp
trun_cmd=`mktemp`
# make it cd back to where we are now
echo "cd `pwd`" >$trun_cmd
# make the title bar contain the command being run
echo 'echo -n -e "\033]0;'$*'\007"' >>$trun_cmd
# clear window
echo clear >>$trun_cmd
# the shell command to execute
echo $* >>$trun_cmd
# make the command remove itself
echo rm $trun_cmd >>$trun_cmd
# make the file executable
chmod +x $trun_cmd
# open it in Terminal to run it in a new Terminal window
open -b com.apple.terminal $trun_cmd
You could also invoke the new command feature of Terminal by pressing the Shift + ⌘ + N key combination. The command you put into the box will be run in a new Terminal window.