Linuxでファイルをコピーする際、「同名のファイルがあっても確認なしで強制的に上書きしたい」ということ、よくありますよね。
「それなら -f オプションをつければいいじゃん!」と思って cp -f を実行したのに、なぜか 「overwrite ‘xxxx’?」と確認を求められて困った 経験はありませんか?
今回は、cp -f で強制上書きできない原因と、それを一発で解決する裏技、さらに crontab 内での挙動について解説します。
1. 基本:ファイルを強制的に上書きコピーする
本来、cp コマンドで確認なしの強制上書きを行うには、-f(–force)オプション を使用します。
基本のコマンド
cp -f <コピー元> <コピー先>
これで、コピー先に同名のファイルが存在する場合でも、ユーザーへの確認なしで上書きされる……はずです。
2. なぜ -f を付けても確認が求められるのか?(原因はエイリアス)
-f を付けたのに確認プロンプトが出てしまう場合、原因はOSの 「エイリアス(別名設定)」 にあります。
CentOSやRocky Linux、Ubuntuなど多くのLinuxディストリビューションでは、ユーザーが誤ってファイルを消してしまわないよう、デフォルトで cp コマンドが以下のようにエイリアス登録されています。
alias cp='cp -i'
-i は「上書きする前に確認を求める」オプションです。この設定のせいで、裏で自動的に -i が呼び出されてしまい、いくら後ろに -f を付けても確認を求められてしまうのです。
3. 解決策:コマンドの先頭に「\」をつける!
このエイリアス設定を一時的に無視して、コマンド本来の挙動(純粋な -f)をさせたい場合は、コマンドの先頭にバックスラッシュ(環境によっては円マーク \)を付けます。
確実に強制上書きするコマンド
\cp -f <コピー元> <コピー先>
先頭に \ を付けるだけで、システムに登録されたエイリアス(cp -i)を完全に無効化し、文字通りの強制上書きを実行することができます。
4. 逆に対話的(確認を求める)にコピーしたい場合
安全のために1ファイルずつ確認しながら上書きしたい場合は、明示的に -i オプション を使用します。(エイリアスが効いている環境なら、オプションなしの cp でも同様です)
cp -i <コピー元> <コピー先>
コピー先に同名ファイルがある場合、画面に確認が表示され、y(Yes)または n(No)の入力を求められます。
💡 補足:crontab の中では「\cp」はどう書く?
シェルスクリプトを crontab(クーロン)に登録して自動実行させる際、「cronの中でも \ を重ねてエスケープ(\\cp)しなきゃいけないのかな?」と疑問に思うかもしれません。
結論から言うと、crontab の中でも \cp はそのまま記述して問題なく動作します。
そもそも、cronが実行されるシェル環境では、上記のようなインタラクティブ(対話型)用のエイリアス(cp -i)は最初から読み込まれない仕様になっていることが多いですが、安全策としてスクリプト内に \cp -f と書いておく場合でも、\ をさらにエスケープする必要はありません。そのまま使えます!
まとめ
-
cp -fで確認が出てしまうのは、システム標準のalias cp='cp -i'が原因。 -
エイリアスを無視して確実に強制上書きしたいなら、先頭に
\をつけて\cp -fと書く。 -
cron(crontab)の中でも
\cpはそのまま使用可能。
インフラ運用の自動化スクリプトなどを書く際、確認プロンプトで処理が止まってしまうのを防ぐための必須テクニックです。ぜひ覚えておいてくださいね!
