He estado tratando de averiguar cómo ejecutar un comando bash en una nueva ventana de Max OS X Terminal.app. Como ejemplo, así es como ejecutaría mi comando en un nuevo proceso de bash:
bash -c "my command here"
Pero esto reutiliza la ventana de terminal existente en lugar de crear una nueva. Quiero algo como:
Terminal.app -c "my command here"
Pero, por supuesto, esto no funciona. Soy consciente del comando "open -a Terminal.app", pero no veo cómo enviar argumentos a la terminal, o incluso si hice qué argumentos usar.
Respuestas:
Una forma en la que puedo pensar en hacerlo es crear un archivo .command y ejecutarlo así:
echo echo hello > sayhi.command; chmod +x sayhi.command; open sayhi.command
o use applecript:
osascript -e 'tell application "Terminal" to do script "echo hello"'
aunque tendrá que escapar de muchas comillas dobles o no podrá usar comillas simples
fuente
osascript -e "tell application \"Terminal\" to do script \"echo '$variable'\"'
; exit
al final de los comandos del script de shell, comodo script "echo hello; exit"
. Aún necesita cerrar la ventana por separado.Solución parcial:
Pon las cosas que quieres que se hagan en un script de shell, así
#!/bin/bash ls echo "yey!"
Y no olvides '
chmod +x file
' para hacerlo ejecutable. Entonces tú puedesy se ejecutará en una nueva ventana. Agregue '
bash
' al final de la secuencia de comandos para evitar que la nueva sesión salga. (Aunque es posible que tenga que averiguar cómo cargar los archivos rc de los usuarios y todo eso ...)fuente
/Users/{username}
. ¿Hay alguna forma de mantener la carpeta de contexto igual que la ventana de la terminal principal que la abrió?He estado intentando hacer esto por un tiempo. Aquí hay un script que cambia al mismo directorio de trabajo, ejecuta el comando y cierra la ventana del terminal.
#!/bin/sh osascript <<END tell application "Terminal" do script "cd \"`pwd`\";$1;exit" end tell END
fuente
tab 1 of window id 7433
stdout en el shell de lanzamiento . Para suprimir eso, coloque>/dev/null
antes<<END
.En caso de que a alguien le importe, aquí hay un equivalente para 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
fuente
Aquí hay otra versión (también usando 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'
ver: codesnippets.joyent.com/posts/show/1516
fuente
Hice una versión funcional de la respuesta de Oscar, esta también copia el entorno y los cambios en el directorio apropiado
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" }
Puedes usarlo así:
new_window my command here
o
fuente
TMP_FILE="tmp.command"
podría ser un problema si inicia más de un proceso simultáneamente. Sugeriría reemplazarlo porTMP_FILE=$(mktemp "/tmp/command.XXXXXX")
Aquí está mi increíble script, crea una nueva ventana de terminal si es necesario y cambia al directorio en el que se encuentra Finder si Finder está al frente. Tiene toda la maquinaria que necesitas para ejecutar comandos.
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
fuente
Un colega me preguntó cómo abrir MUCHAS sesiones ssh a la vez. Usé la respuesta de cobbal para escribir este 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
Al actualizar la lista de comandos (no tienen que ser invocaciones ssh), obtendrá una ventana abierta adicional para cada comando ejecutado. El
sleep 60
al final está ahí para mantener los.command
archivos mientras se ejecutan. De lo contrario, el shell se completa demasiado rápido, ejecutando la trampa para eliminar el directorio temporal (creado por mktemp) antes de que las sesiones iniciadas tengan la oportunidad de leer los archivos.fuente
También puede invocar la nueva función de comando de Terminal presionando la
Shift + ⌘ + N
combinación de teclas. El comando que coloque en el cuadro se ejecutará en una nueva ventana de Terminal.fuente
A este guión lo llamo trun. Sugiero ponerlo en un directorio en su ruta ejecutable. Asegúrese de que sea ejecutable así:
Luego, puede ejecutar comandos en una nueva ventana simplemente agregando trun antes de ellos, así:
trun tail -f /var/log/system.log
Aquí está el guión. Hace algunas cosas elegantes como pasar sus argumentos, cambiar la barra de título, limpiar la pantalla para eliminar el desorden de inicio de la shell, eliminar su archivo cuando haya terminado. Al usar un archivo único para cada nueva ventana, se puede usar para crear muchas ventanas al mismo tiempo.
#!/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
fuente
$*
todo arruinará cualquier cita no trivial en la entrada. Tú quieres en su"$@"
lugar.open -b com.apple.terminal
. Gracias