.htaccessのmod_rewriteでのリダイレクトする

ノスタルジックなシステムにおいて下記のようなURLを

http://localhost/post.php?user=hoge&id=10

下記のようにリダイレクトしたい場合

http://localhost/post/hoge/10

.htaccessには下記のように記述します。

RewriteCond %{QUERY_STRING} user=([a-z]+)&id=([0-9]+)
RewriteRule ^post\.php$ /post/%1/%2? [L,R=301]

最後の?をつけないとクエリがそのまま渡ります。クエリをそのまま渡したい場合は削除すると良い。

リダイレクトしたあとのURLを下記のように書き換えてユーザーにアクセスさせる場合、このURLでも上記のリダイレクト対象となりますので

RewriteRule ^post/([a-z]+)/([0-9]+)$ /post.php?action=tag&id=$1 [QSA,L]

別のファイルでURL書き換えをさせるのが良かった

RewriteRule ^post/([a-z]+)/([0-9]+)$ /post2.php?action=tag&id=$1 [QSA,L]

JavaScriptでリンク先をPCではポップアップウィンドウで開きモバイルでは通常通り別タブで開く

管理画面でモバイルの場合は画面が狭いのでページを別タブで開きたいが、PCでは画面が広いのでポップアップウィンドウで表示したい場合がある。そんな時のサンプルコードです。

<ul>
<li><a href="http://localhost/a.html" class="popup" target="_blank"></a></li>
<li><a href="http://localhost/b.html" class="popup" target="_blank"></a></li>
<li><a href="http://localhost/c.html" class="popup" target="_blank"></a></li>
</ul>
(function() {
// windowFeaturesオプションには多くの設定値があるがモダンブラウザでは無視されている
// 横幅と縦幅は無視されないのでそれだけ設定している
// サイズはブラウザの表示領域縦横の50%を確保する
let option = {
width: window.innerWidth * 0.5,
height: window.innerHeight * 0.5
};
document.querySelectorAll('a.popup').forEach(function(a) {
a.addEventListener('click', function(event) {
// ポップアップウィンドウの設定
let name = a.href + "の名前だよ";
// 下記のモバイルデバイスのいずれにも一致しないかをboolで返す
let isNotMobile = ["iPhone", "iPod", "Android", "Mobile"].filter(function(key) {
return navigator.userAgent.indexOf(key) !== -1;
}).length === 0;
// PCではポップアップウィンドウで表示してイベントキャンセル(モバイルデバイスでは普通に開く)
if(isNotMobile) {
window.open(a.href, name, Object.keys(option).map(function(key) { return key + "=" + option[key]; }).join(",")).focus();
event.stopPropagation();
event.preventDefault();
}
});
});
})();

最近フロントエンドのこと書かなくなっちゃって寂しいのでちょっと書いていきます。

Rustでno method named `foreach`と言われたら

あるサイトでforeachが使えると言われたので使ったらない

error[E0599]: no method named `foreach` found for type `std::vec::IntoIter<hoge::Hoge>` in the current scope

for_eachの間違いであった

hoge.for_each(|value| {
println!("{}", value);
});

情けない

Ubuntuのコマンドラインで外部ディスクをLUKSフォーマットする

USBで外付け記憶領域を接続します。その後ディスク一覧を確認して接続したディスク名を確認します。

sudo fdisk -l

該当のディスクをluksFormatで暗号化初期化します。

sudo cryptsetup luksFormat /dev/sdb

LUKSパーティションをbackupという名前でマッピングする。

sudo cryptsetup luksOpen /dev/sdb backup

ちなみに、マッピングを取り消す時は下記のようにする。

sudo cryptsetup luksClose backup

マッピングされた領域は最初なんでもない場所なので、その部分をext4でフォーマットします。

sudo mkfs.ext4 /dev/mapper/backup

上記の手順を踏むことで結果的に、ディスクはLUKS暗号化された状態になり、マッピングして暗号化を解除することで、ext4の領域が出現するようになります。

ちなみに、もし既存のUbuntuが暗号化されておらず、これから暗号化したいという人がこの記事にたどり着いた場合は、あとから暗号化できないのでインストールし直すのが一番ラクかなと思います。そのへんについては別記事にまとめているので参考にしてください。

https://qiita.com/setouchi/items/678df2be77c1f0aa5243

Dell XPS 13 9370にUbuntu 18.10とWindows 10をデュアルブートさせて入れる

Windowsでしかできない作業(特殊なスキャナーとかプリンターなど)があります。Linux上の仮想マシンにWindowsを入れても画面への出力に問題などがあり、やはり直インストールしたほうが安定します。Windowsマシンを組み上げるのが最も楽で安定しますが、滅多に使わないWindowsのために場所取るのも嫌なのでノートPCにデュアルブートするのが理想です。

ただ、わかってしまえば何てことはないですが、様々な障害にぶち当たり1日無駄になりました。

※UbuntuのインストールについてはUbuntu 18.10をLUKS暗号化してインストールするにまとめたので参考にしてください。この記事ではこの作業の続きについて解説しています。

BIOSアップデート後はDELL付属のWindowsが利用できなくなる

まずはじめにDELLのPCには工場出荷状態にする仕組みがあり、それによってWindowsをクリーンインストールする機能があります。

工場出荷状態で復元したWindowsは使えない

IMG_20190119_204611.jpg

UbuntuはSATAコントローラをAHCIにしなければ動作しないがDELL付属のWindows(DELLのサポートアシスタントで復旧できるイメージ)は昔は問題なかったがBIOSを最近アップデートしてからは、SATAコントローラをRaidにしなければいけなくなった。UbuntuファーストなのでWindowsを起動するためにSATAコントローラを変更するつもりはないので正確には未検証。

Windowsを自力で新規インストールすると問題ない

解決策としてはWindowsをDELLの復旧オプションを使わずに自力でインストールすること。この時WindowsのDSP版でもいいのでOSを別途購入しなければいけないと思います。DELLのライセンスキーって使えるのかね。(自力インストールの場合はDell Mobile Connect Driverを入れないとかなんとかだが、一通り動いていたので気にしていないが、後で読んで追記します。)

UEFI Boot USBを作成してWindowsを自力インストールする

DELL XPS 13 9370ではUEFI Boot USBでなければインストールできない。つまり、Windowsからダウンロードしてきたisoイメージをsudo dd if=~/Downloads/Win10_1809Oct_Japanese_x64.iso of=/dev/sda bs=1048576するだけではだめで、デバイスをFAT32でフォーマットしたあとに下記のような手順でisoファイルをシステムにマウントし中のデータをコピーする必要があります。

sudo mkdir /media/cdrom
sudo mount -o loop -t udf,iso13346 ~/Downloads/Win10_1809Oct_Japanese_x64.iso /media/cdrom

GUIでドラックアンドドロップでコピーでも良いが、CLIでやるなら以下のような感じ。 

rsync -ahvz --progress /media/cdrom/ /media/user/windows

コンピューター起動時にGNU GRUBが立ち上がるようにする

GNU GRUBはデュアルブートする時に便利なブートローダでUbuntuを入れると最初から入ってくると思います。これのおかげでコンピューター起動後はOSを選択して起動することができるのですが、Windowsをインストールすると(DELLの復旧オプションを使っても同じ)Windows Boot Managerが先に起動し、Windows以外のOSを起動するには起動直後にF12を連打する必要があるという、Microsoftファーストな状態になります。

Boot SequenceにUbuntuが残っている場合

私の場合はWindows以外のすべてのBoot Sequenceが削除されてしましたが、もしかしたら残っている場合は単にUbuntuの優先順位を最上位にすれば良い。

Windows Boot Manager以外が消えた場合

私と同じようにすべて消されている場合は、コンピュータ起動直後にF2を連打しBIOSの設定画面を開き、GeneralのBoot SequenceでAddを選択し、Boot Option NameにはUbuntu、File System ListにはUbuntuがインストールされているはずのパーティションを選択、File Nameには\EFI\ubuntu\shimx64.efiと入力して追加を完了し、最後にUbuntuの優先度をWindows Boot Managerの上に移動し適用をします。

すべて消えてしまったのはBIOSの設定がリセットされたのか、私が誤ってリセットしたのかは不明。

おわり

BIOSの設定をいろいろ変更しながら進んでいったので、いろいろアップデートしちゃったり、最初の設定がわかんなくなったり、BIOSの設定元に戻したのに戻らない項目が出たりと微妙だけど、結果的にほとんどの設定を浅く理解できました。

また後々問題出てくると思うので追記していきます。

でもノートPC一台でWindowsもUbuntuも使えて部屋もスッキリでございます。

Rustのprintによる標準出力がプログラム実行完了まで出力されないのはラインバッファに溜まっているから

開発の途中でどんな値が流れてきているか一時的に変数の値を標準出力に出して確認することがある。例えばKotlinならprintln、PHPならvar_dump、JavaScriptならconsole.logを呼ぶのと同じ気持ちです。

はじめてテストでコードを書いた時、下記のように出力を試みたのですがプログラムの終了まで出力されませんでした。

print!("hoge");

どうやらprintはデフォルトでラインバッファされるらしいので下記のようにしてフラッシュしてあげるか

print!("hoge");
stdout().flush().unwrap();

改行付き出力ができるprintlnを使うと良いみたい。通常はこっちを使うのが正しいそうです。

println!("hoge");

今まで触った言語で指定していないのにバッファに貯まるってのがあまりなかったので新鮮でございました。下記は参考にしたページでございます。

Rustで`P` cannot be formatted with the default formatterと言われる場合の対応

error[E0277]: `P` doesn't implement `std::fmt::Display`
--> src/main.rs:263:22
|
263 |         print!("{}", path);
|                      ^^^^ `P` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `P`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= help: consider adding a `where P: std::fmt::Display` bound
= note: required by `std::fmt::Display::fmt`

デフォルトフォーマッターではフォーマットができない。Pには実装されていない。{:?}もしくはプリティに出力するなら{:#?}を使う。もしくはPになんかしたら?みたいなことが書いているように見える、多分。この時同時に対象の構造体には#{drive(Debug)]を付与するらしい。

#[derive(Debug)]
struct Hoge {
num: u32,
num2: u32,
}

Rustでcargo runが突然エラー終了するようになった場合の対策

さっきまで通っていたコンパイルがなぜか突然通らなくなった。試しにcargo cleanしてからcargo runしたらうまく動くようになった。

そういえばJavaもgradle cleanしてからgradle buildしてたけど、Javaの場合はIDEでテストしてたからあまり頻繁にrunとか直接しなかったし、RustもIntelliJで動かせるようにしてみようかな。

追記:というわけでIntelliJでRustのプロジェクトを開き、プラグインインストール後にmain関数の横にいる再生ボタンを押せばテスト可動させられるようになりました。ファイルを編集したら停止&スタートで何度も更新して確認できます。Javaプロジェクトに比べて実行までの速度が速くていいですね。

Screenshot from 2019-01-16 11-34-37.png

Ubuntuにnodejsとnpmとyarnをインストールする

簡単に入る時代になりました。

sudo apt install -y nodejs npm

複数のバージョンを共存させるにはnを使うと良いです。

yarnについては下記のようにして入れます。

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn

参考

https://yarnpkg.com/lang/en/docs/install/#debian-stable