新しいMac OS Xターミナルウィンドウでコマンドを実行する


89

新しいMax OS X Terminal.appウィンドウでbashコマンドを実行する方法を理解しようとしています。例として、新しいbashプロセスでコマンドを実行する方法を次に示します。

bash -c "my command here"

ただし、新しいウィンドウを作成する代わりに、既存のターミナルウィンドウを再利用します。私は次のようなものが欲しい:

Terminal.app -c "my command here"

しかし、もちろんこれは機能しません。「open -a Terminal.app」コマンドは知っていますが、引数をターミナルに転送する方法がわかりません。また、使用する引数を指定した場合でもわかりません。


いつでも設定を開き、[プロファイル]タブに移動し、[シェル]ページに移動して、そこに起動コマンドを設定できます。アプリケーションが開かれたときにのみ実行されますが、ハッキーな代替品よりもうまく機能します!
Zane Helton 2015年

回答:


95

私の頭の上でそれを行うと考えることができる1つの方法は、.commandファイルを作成して次のように実行することです。

echo echo hello > sayhi.command; chmod +x sayhi.command; open sayhi.command

またはapplescriptを使用します。

osascript -e 'tell application "Terminal" to do script "echo hello"'

ただし、多くの二重引用符をエスケープする必要があるか、単一引用符を使用できない


最初の方法を決めました。それはかなりハックっぽいですが、それは機能し、私のコマンドや何かで引用符がエスケープされることを心配する必要はありません。ありがとう。
Walt D

3
コマンドをパラメーター化して実行する必要がある場合は、一重引用符と二重引用符を入れ替えることができます。ただし、これを正しく行うには、違いを理解する必要があります。osascript -e "tell application \"Terminal\" to do script \"echo '$variable'\"'
tripleee 2016

誰かが愚かな残されたターミナルウィンドウを閉じる方法を知っていますか?
Nicholas DiPiazza

; exitように、シェルスクリプトコマンドの最後に追加しますdo script "echo hello; exit"。それでも、ウィンドウを個別に閉じる必要があります。
tripleee

65

部分的な解決策:

あなたがやりたいことをシェルスクリプトに入れてください

#!/bin/bash
ls
echo "yey!"

そしてchmod +x file、実行可能にするために ' 'を忘れないでください。次にできます

open -a Terminal.app scriptfile

新しいウィンドウで実行されます。bashスクリプトの最後に「」を追加して、新しいセッションが終了しないようにします。(ただし、ユーザーのrcファイルやその他のものをロードする方法を理解する必要があるかもしれません。)


7
新しく開いたウィンドウのコンテキストは、ユーザーのルートフォルダーのよう/Users/{username}です。コンテキストフォルダーを開いた親ターミナルウィンドウと同じに保つ方法はありますか?
ジョニー・

>ユーザーのrcファイルなどをロードする方法を理解する必要があるかもしれませんが、これにはbash -lを使用してください
Aivar

35

私はしばらくこれをやろうとしてきました。次のスクリプトは、同じ作業ディレクトリに移動し、コマンドを実行して、ターミナルウィンドウを閉じます。

#!/bin/sh 
osascript <<END 
tell application "Terminal"
    do script "cd \"`pwd`\";$1;exit"
end tell
END

受け入れられたスクリプトを嫌い、あなたの1つは現在のディレクトリの問題を解決します。ありがとう!
Marboni

素晴らしいソリューション。ただしtab 1 of window id 7433起動シェルでstdoutのような出力をします。それを抑制するには、の>/dev/null 前に配置し <<ENDます。
mklement0 2012

1
これは本質的に端末ウィンドウを閉じません。コマンドインタープリターを終了するだけです。Terminal.appは、ウィンドウを自動的に閉じるか、コマンドインタープリターのクリーン終了時に構成する必要があります。
user66001 2013年

8

誰かが気にする場合のために、ここに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

3

これもまた別の見方です(これも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' 

参照:codesnippets.joyent.com/posts/show/1516


3

私はオスカーの答えの関数バージョンを作りました、これは環境をコピーして適切なディレクトリに変更します

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"
}

次のように使用できます。

new_window my command here

または

new_window ssh example.com

1
TMP_FILE="tmp.command"複数のプロセスを同時に開始すると、ラインが問題になる可能性があります。交換することをお勧めしますTMP_FILE=$(mktemp "/tmp/command.XXXXXX")
duthen 2017年

2

これが私の素晴らしいスクリプトです。必要に応じて新しいターミナルウィンドウを作成し、Finderが最前面にある場合はFinderがあるディレクトリに切り替えます。コマンドを実行するために必要なすべての機構を備えています。

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

1

同僚から、一度にたくさんのSSHセッションを開く方法を尋ねられました。私はこのスクリプトを書くためにコバルの答えを使いました:

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

コマンドのリストを更新することにより(コマンドはssh呼び出しである必要はありません)、実行されるすべてのコマンドに対して追加の開いているウィンドウが表示されます。sleep 60最後には、維持することがあり.command、彼らが実行されている間、周りのファイルを。そうでない場合、シェルは完了が速すぎて、起動されたセッションがファイルを読み取る機会を得る前に、トラップを実行して一時ディレクトリ(mktempによって作成された)を削除します。


0

キーの組み合わせを押すことにより、ターミナルの新しいコマンド機能を呼び出すこともできShift + ⌘ + Nます。ボックスに入力したコマンドは、新しいターミナルウィンドウで実行されます。


もちろん知っておくと便利ですが、プログラムで行う必要があります。私のプログラムで.commandファイルを生成してから開くことは、妥当な(少しハックな場合)ソリューションです。
ウォルトD

0

このスクリプトをトランと呼びます。実行可能パスのディレクトリに配置することをお勧めします。次のように実行可能であることを確認してください:

chmod +x ~/bin/trun

次に、次のように、その前にtrunを追加するだけで、新しいウィンドウでコマンドを実行できます。

trun tail -f /var/log/system.log

これがスクリプトです。引数を渡す、タイトルバーを変更する、画面をクリアしてシェルスタートアップの混乱を取り除く、完了時にファイルを削除するなど、いくつかの手の込んだことを行います。新しいウィンドウごとに一意のファイルを使用することで、同時に多くのウィンドウを作成できます。

#!/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

1
$*全体の誤った使用法は、入力の重要な引用を破壊します。"$@"代わりにしたいです。
tripleee 2018

探していましたopen -b com.apple.terminal。ありがとう
Ebru Yener
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.