Linux上で特殊文字を含む名前のファイルの削除方法
はじめに
コマンドの操作ミスやスクリプト出力の文字化けなどで特殊文字を含む名前でファイルができてしまい、単にrmコマンドでは削除できない時の削除方法。
いざという時のためにメモ。
実験用のファイル
temp $ ls "ccc.txt -bbb.txt aaa.txt temp $
他にもありえますが用意するのがめんどくさかったのと、今回の削除方法はファイル名によらず使えるのでこれで。
実験
とりあえず用意したファイルを普通に消そうとするとどうなるか見てみます。
先頭がダブルクォートのファイル名
temp $ rm "ccc.txt > temp $
次の入力を待たれてしまいます。
先頭がハイフンのファイル名
temp $ rm -bbb.txt rm: illegal option -- b usage: rm [-f | -i] [-dPRrvW] file ... unlink file temp $
rmコマンドのオプションと解釈されてしまいます。
解決方法
いろいろなやり方があるのですが、汎用的な方法を。
手順1 ls -iでinode番号を確認
temp $ ls -i 2991451 "ccc.txt 2991471 -bbb.txt 2991475 aaa.txt temp $
ファイル名の前に表示されているのがinode番号です。
手順2 確認したinode番号を指定して削除
temp $ rm `find . -inum 2991451` temp $ ls -bbb.txt aaa.txt temp $ rm `find . -inum 2991471` temp $ ls aaa.txt temp $
削除できました。
実際にやる場合は、事前の削除対象の確認を忘れずに。
おまけ
実験用に使ったパターンのものは別の方法でも削除できます。
先頭がダブルクォートのファイル名
2つ方法があります。
先頭がハイフンのファイル名
こちらは、ダブルクォートの方法では消せないので以下の方法を使います。
- コマンドのオプションに
--
を指定するrm -- -bbb.txt
iOSDC Japan 2017に行ってきました
子どもができてからというもの、なかなか勉強会やイベントに参加できなくなっていましたが、久々に参加してきました。
かなり悩みつつセッションの選択をしたなかで、特に印象に残ったものをあげます。
両OSやるマンという選択
意外とAndroidも開発してるよって人が多かったのが印象的でした。
違いを意識してプロダクトに落とし込むことが一番重要っていう部分は同意しかなくて、ディレクターさんやデザイナーさんにこそ共有したいなーと思いました。
Android開発もやってみよっかなーという気分になりました。
アプリエンジニアはどのように事業に貢献すべきか
近々、初めてBtoCのサービス開発に関わる予定なのですが、同じようなことに悩むんだろうかと思いつつ聞いていました。
気になったキーワード
- アプリを使うことがユーザーにとってやりたいことではない
- ユーザーが喜ぶ体験を理解して、アプリ上で実現する
- アプリ以外も含めてサービスでありユーザー体験である
何度か読んで、自分なりの考えをまとめてみるつもり。
結婚式を支えた技術 Firebaseを活用したサーバレスiOSアプリケーション開発
結婚式の写真を共有してもらうために1ヶ月でアプリを作ってしまうという素敵なお話。
身近なところにある問題を解決するのは、ユーザーも近くてフィードバックもらいやすいし、なにより解決すれば喜んでもらえるし、いいことずくめですね。
我が家でも、妻からこんなアプリできないの?みたいなことをたまに言われるのですが、子どもと遊ぶのを言い訳にしてしまっていて反省。
とりあえずFirebase触ってみようと思いました。
全体通しての感想
めちゃめちゃ楽しかったです。
以下、楽しかったことを雑にまとめます。
- オープニングから力の入ったムービーでテンションあがる
- セッションはどれも面白く、同じ枠で聞きたいものがかぶりまくって泣く泣く選択するという贅沢な状況
- 懇親会でもないのにビールが配られて、飲みながら聞くLT最高
- 運営の方々が、ほんとによく動いていて、とにかくスムーズな運営が印象的
ただ、2日目の途中で体調を崩してしまい、途中で帰らざるを得なくなってしまったのが心残りです。
来年も開催されたら、最後まで参加するぞ。懇親会も参加できたらいいな。
Swiftはプロパティもオーバーライドできる
バージョン
- Swift 3.0.2
- Xcode 8.2.1
クラスのプロパティ
知らなかっただけなのですが、Swiftはプロパティもオーバーライドできます。
使い方次第で便利に使えそう。
サンプルコード
プロパティのオーバーライドとプロパティ監視を組み合わせて、ボタンが無効化されたらアルファ値を変えるコードです。
import UIKit class CustomButton: UIButton { override var isEnabled: Bool { didSet { super.isEnabled = isEnabled self.alpha = isEnabled ? 1.0 : 0.4 } } } let customButton: CustomButton = CustomButton() print(customButton.isEnabled) // true print(customButton.alpha) // 1.0 customButton.isEnabled = !customButton.isEnabled print(customButton.isEnabled) // false print(customButton.alpha) // 0.4
UIViewからUITableViewのカスタムセルを作るとボタンタップイベントが取れない
現象
UITableVIewのカスタムセルにボタンを置いて、タップ用の処理を書いたがタップイベントを検知できない。
原因
ボタンの上のレイヤーに、UITableViewCellContentView
というビューが描画されており、このビューに邪魔されてタップイベントが検知できていなかったため。
根本原因
カスタムセルのxibファイルを、UITableViewCell
ではなく、 UIView
を使って作成していたため。
UITableViewCell
で作ったxibは、UITableViewCellContentView
の上に自分の配置したパーツが描画されています。
ちなみに、xibファイルの新規作成すると、デフォルトで UIView
が置いてあるというXCodeのおせっかい機能のがほんとの原因かもしれません。
対策
カスタムセルを作る際には、xibファイルのデフォルトで置いてある UIView
を消して、UITableViewCell
を置くと良いです。
または、新規ファイルを作成する際に、クラスファイルから作成して、 Cocoa Touch Class
を選択して、次の画面で Also create XIB file
にチェックを入れると、勝手に UITableViewCell
を配置したxibファイルを生成してくれます。
AutoLayoutに慣れてる人には当たり前なのかもしれないですが、ちょっとわかりにくいなーと思いました。
2016年の振り返り
今年もあんまりブログ書けなかったけど、振り返りはしておく。
お仕事全般
こまごまPHPもやったけど、ほぼSwiftでiOSアプリ開発ばっかりだった。
チームでのアプリ開発を経験できたり、RxSwift触ってみたり楽しかった。
プチSCMBCとかを開催して、ちょっとずつプルリクエスト方式での開発ができるようになってきた。
Qiita:Team
去年に引き続き、積極的に投稿するようにしていた。
だんだん書いてくれる人が増えてきて嬉しい。
少しは役に立っているのかも。
社内勉強会
Bitbucketを使うことが増えてきたので、プチSCMBCみたいなことをした。 コンフリクト祭りが楽しかった。
全職種向けにバージョン管理についての勉強会を開催して日付zipがなぜダメなのかを伝えた。
社外勉強会など
ほぼ参加できなかったけど、まあ、これは仕方ない。
プライベート
第二子である次男が生まれて家の中がさらに賑やかになった。
長男が保育園に通うようになって、より時間を効率的に使う必要が出てきた。
早めに出社して勉強してたのが、子どもを寝かしつけてからの時間に変わった。
たまに一緒に寝落ちしちゃうのどうにかしたい。
来年の目標
- Qiita:Teamをディレクターさん、デザイナーさんも使うようになってきたのでそっち向けの記事も書く
- Swift環境での自動テストを導入する
- iOSアプリ開発に偏った1年だったので、Web開発もうちょっとがんばる
- 何かしらアウトプットする
配列の要素をオプショナルバインディング
はじめに
コードレビューで、ちょっと不思議なコードがあったのでメモ。
結論
配列の添字アクセスをオプショナルバインディングしてもビルドエラーにならないけど、わかりにくいのでやめたほうがいい。
コード
var hoge:[Int] = [] // hogeを更新する処理など if let n: Int = hoge[0] { //ランタイムエラー print(n) } else { print("nothing") }
一見すると良さそうですが、配列が空っぽなのでコメントした行で fatal error: Index out of range
になります。
当たり前といえば当たり前ですね。
改善案
配列でこういった判定を行うなら、空配列の判定したほうがわかりやすい気がします。
if hoge.isEmpty { print("nothing") } else { print(hoge[0]) }
そもそも、配列アクセスでnil
が返る可能性を想定したコードになっていますが、hoge
はInt
型の配列であって、Optional<Int>
型の配列ではないので、オプショナルバインディングは適切ではないです。
なんでビルドエラーにならないのかは謎です。
どうしてもオプショナルバインディングしたい場合
if let n: Int = hoge.first { print(n) } else { print("nothing") }
今回の場合は、配列の最初の要素にアクセスしたいので、Array
クラスの first
プロパティでOK。
first
はオプショナル型なので問題なし。
似たようなプロパティとして最後の要素を参照する last
もあります。
どちらも正確には Array
クラスに適用している CollectionType
プロトコルの特徴ですが。
PHPで画像やcssの404エラーでセッション切れになる現象
はじめに
FuelPHPを使っていて、セッションが切れることがあり調査していました。
ググるとドキュメントルートにファビコンが存在していないと発生するなどの記事がヒットするのですが、ファビコンだけでなく読み込んでいる画像やcssがなくても同じ事象が発生することがわかったのでまとめておきます。
結局FuelPHPだけの話ではなかったです。
原因
FuelPHPに限らず、PHPのWebアプリケーションフレームワークだと、たいてい.htaccess
にこんな感じの設定があります。
リクエストされたパスがファイルやディレクトリじゃなかったら、フロントコントローラーであるindex.php
に処理を投げるというものです。
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php$1 [L]
通常、画像やcssは最初の条件に該当するのでindex.php
で処理しないのですが、ファイルが存在しない場合、どちらの条件にも該当せずindex.php
で処理することになります。
コントローラーには画像やcssファイル名のアクションはないので、最終的に404に流れます。
index.php
内(というか、その先のコントローラーなど)で、FuelPHPで言うフラッシュセッションのような次のリクエスト時に消えるセッションを使用していると、404リクエストで消えてしまうためセッション切れが発生します。
生存期間の長い通常のセッション使っても解決するのですが、フォームデータの削除し忘れとか嫌ですし。
対策
コントローラのアクション以外をindex.php
で処理しなければいいので、.htaccess
の設定をこんな感じにすれば良いです。
特定の拡張子(この例ではcss/jpeg/png)の場合、index.php
で処理しないようにしています。
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !^.*\.(css|jp?g|png)$ RewriteRule ^(.*)$ /index.php$1 [L]