私は自分がたくさん繰り返していることに気づきます:
mkdir longtitleproject
cd longtitleproject
ディレクトリ名を繰り返さずに1行で行う方法はありますか?私はここでバッシュしています。
組み込みコマンドはありませんが、mkdir
を呼び出してcd
を呼び出す関数を簡単に作成できます。
mkcd () {
mkdir "$1"
cd "$1"
}
このコードを~/.bashrc
ファイルに入れます(kshユーザーの場合は~/.kshrc
、zshユーザーの場合は~/.zshrc
)。 mkcd
という関数を定義しています。 "$1"
は、実行時に関数の引数に置き換えられます。
このシンプルなバージョンにはいくつかの欠陥があります:
-p
オプションをmkdir
に渡します。 (これは、タイプミスが検出されなくなるリスクを高めるため、望ましい場合と望ましくない場合があります。たとえば、既存のmydierctory
内にnewsub
を作成するつもりであった場合、mkcd mydierctory/newsub
はmydirectory
とmydierctory/newsub
を喜んで作成します。)-
で始まり、-
ではない場合、mkdir
およびcd
はオプションとして解釈します。 -
だけの場合、cd
は$OLDPWD
を意味すると解釈します。 +
の後に0個以上の数字が続く場合、zshのcd
はそれをディレクトリスタックのインデックスとして解釈します。引数の前に--
を渡すと、最初の問題を修正できますが、他の2つの問題は修正できません。相対パスの場合、引数の前に./
を追加することで、これらの問題をすべて修正できます。mkdir
はCDPATH
に追従しませんが、cd
は追従します。つまり、CDPATH
を.
で始まらない値に設定した場合(明らかに少し変わった設定です)、cd
は以前とは異なるディレクトリに移動する可能性があります作成したばかりです。相対パスの前に./
を付加すると、これが修正されます(CDPATH
が無視されます)。mkdir
が失敗した場合、cd
を実行しようとします。修正:&&
を使用して2つのコマンドを区切ります。それでもかなり単純です:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
このバージョンでは、cd
が、あるEdgeケースでmkdir
が作成したディレクトリとは別のディレクトリに移動する可能性があります。mkcd
への引数に..
が含まれ、シンボリックリンクを通過する場合。たとえば、現在のディレクトリが/tmp/here
であり、mylink
が/somewhere/else
へのシンボリックリンクである場合、mkdir mylink/../foo
は/somewhere/else/foo
を作成し、cd mylink/../foo
はfoo
に変更します。シェルはシンボリックリンクも独自の現在のディレクトリで追跡するため、引数でシンボリックリンクを検索するだけでは十分ではないため、cd /tmp/mylink; mkdir ../foo; cd ../foo
は新しいディレクトリ(/somewhere/else/foo
)ではなく/tmp/foo
に変更されます。このための修正は、cd
組み込み関数がすべての..
パスコンポーネントを最初に解決できるようにすることです(foo
が存在しない場合、foo/..
を使用しても意味がないため、mkdir
が..
を参照する必要はありません)。
少し悲惨なバージョンの場合、この堅牢な状態になります。
mkcd () {
case "$1" in
*/..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
/*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
/*) mkdir -p "$1" && cd "$1";;
*/../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
*) mkdir -p "./$1" && cd "./$1";;
esac
}
(演習:なぜ最初のcd
呼び出しにサブシェルを使用するのですか?)
Mkdirが失敗した場合は、現在のディレクトリを変更しないようにしたいと思います。シェルが現在のディレクトリに変更する権限を持っていない場合、cd-または$ OLDPWDで元に戻すだけでは十分ではありません。また、cdを呼び出すとOLDPWDが更新されるため、一度だけ実行する(またはOLDPWDを復元する)必要があります。
また、前の行のWordを再入力する必要がない、それほど専門的ではない方法もあります。
cd
と入力して、 Esc. (または Alt+.)前のコマンドの最後の引数を挿入します。cd !$
は、前のコマンドの最後の引数でcd
を実行します。mkdir
をcd
に変更します。ほぼ1時間ごとに次のように入力するので、この動作をスクリプト化することは決してありませんでした...
$ mkdir someDirectory<ENTER>
$ cd !$
ここでbashは!$
最後の行の最後の単語;つまり、入力した長いディレクトリ名。
さらに、このような状況では、ファイル名の補完機能が役立ちます。新しいディレクトリがフォルダー内の唯一のファイルだった場合、 TAB 再入力せずに新しいディレクトリを取得します。
他の回答が示唆しているように、bashがこのような一般的なタスクをスクリプト化できることはクールですが、別のマシンで作業しているときに構文を見逃さないように、bashが提供するコマンドライン編集機能を学ぶ方が良いと思いますカスタムスクリプトが提供する砂糖。
生産性を向上させるためにシェルプロファイルでどのようなカスタマイズを行いましたか? のとおり、次のようにします。
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
つまり、ディレクトリがすでに存在する場合にも機能します。
Oh My Zshを使用する場合、これを正確に行うtakeというコマンドがあります。こんな感じになります。
take myfolder
私は実際にこれを偶然見つけました。私は見たところ、Oh My Zsh GitHub wikiの this cheatsheat にリストされています。これは非常に便利なコマンドで、明らかに自分で作成するのは非常に簡単です。
または、オンザフライで短い変数を作成し、それを2回使用することもできますx = longproject ; mkdir $x ; cd $x
-私が認めていることは、シェルスクリプト関数を使用するよりもまだ長いです:)
ディレクトリを作成するスクリプトを作成し、それにcdを実行して、エイリアスを付けました。そして、ここに私がそれを説明する要点があります。
https://Gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be
ここに言及する価値があるわずかな変形があります:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
これを~/.bash_profile
に追加すると、通常どおりmkdir
を使用できます(source
を実行した後)。ただし、標準ではなく上記の関数を実行します。 mkdir
コマンド。
これは、受け入れられた Gillesによる回答 に従って入力を検証しませんが、ビルトインを(効果的に)オーバーライドする方法を示しています。
ドキュメントから (少し言い換えると):
command mkdir [args]
はmkdir
を実行し、args
はmkdir
という名前のシェル関数を無視します。シェル組み込みコマンドまたはPATHを検索して見つかったコマンドのみが実行されます。ls
という名前のシェル関数がある場合、関数内でcommand ls
を実行すると、関数を再帰的に呼び出す代わりに外部コマンドls
が実行されます
builtin
はcommand
と同様の結果が得られると思います。
環境にmkcd
コマンドを1行で作成します
echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc