「Develop」の版間の差分

提供:senooken JP Wiki
(ログインシェルの確認)
(Tutorial)
 
(同じ利用者による、間の40版が非表示)
200行目: 200行目:
一時的に回避したい場合、[の直前に何か文字があれば解釈されない。スペース開けて[があるとオートコンプリート扱いになる。
一時的に回避したい場合、[の直前に何か文字があれば解釈されない。スペース開けて[があるとオートコンプリート扱いになる。


===== 書式なしペースト =====
[https://qiita.com/kentoak/items/fbba0b9e3e735893a35e Confluenceで書式なしペースト(Ctrl+Shift+V)を有効にする #Confluence - Qiita]
[?]-[キーボードショートカット]-[General]-[▫️Enable General Shortcuts] にしてオフにすると有効になる。
[表の上部にペースト] と競合していたらしい。
==== マクロ ====
==== マクロ ====
[https://ja.confluence.atlassian.com/doc/macros-139387.html マクロ | Confluence Data Center 9.2 | アトラシアン製品ドキュメント]
[https://ja.confluence.atlassian.com/doc/macros-139387.html マクロ | Confluence Data Center 9.2 | アトラシアン製品ドキュメント]
206行目: 211行目:


* [https://ja.confluence.atlassian.com/doc/children-display-macro-139501.html 子ページ表示マクロ | Confluence Data Center 9.2 | アトラシアン製品ドキュメント]
* [https://ja.confluence.atlassian.com/doc/children-display-macro-139501.html 子ページ表示マクロ | Confluence Data Center 9.2 | アトラシアン製品ドキュメント]
* [https://www.ricksoft.jp/blog/articles/001510.html Confluence(コンフルエンス)の一部内容を折りたたみで非表示できる「展開」マクロを使ってみよう - リックソフトブログ]
==== Other ====
===== パーマリンク =====
[https://confluence.atlassian.com/confkb/the-differences-between-various-url-formats-for-a-confluence-page-278692715.html The Differences Between Various URL Formats for a Confluence Page | Confluence | Atlassian Documentation]
Confluenceのページ新規作成時、パーマリンクが自動生成される。規則がある。
以下の条件にマッチしたら、padeId URLになる。それ以外は、タイトル名のURLになる。
* [% & ? / ¥ ; " + :] などのようなURLの予約文字。
* 非ラテン文字。
* ページタイトル末尾が英数字以外の場合。
===== ページ履歴 =====
ページ右上のメニュー-[ページ履歴]から履歴を確認できる。差分も確認できる。
===== ページ移動 =====
[https://ja.confluence.atlassian.com/doc/move-and-reorder-pages-146407727.html ページの移動と順序の変更 | Confluence Data Center 9.2 | アトラシアン製品ドキュメント]
ページ右上のメニュー-[移動]


== Tool ==
== Tool ==
265行目: 292行目:
```
```


===== GNU screen =====
==== GNU screen ====
[https://qiita.com/SAITO_Keita/items/b79ebc5af64aad28fc4a#:~:text=%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E7%8A%B6%E6%85%8B%E3%81%A7%E3%82%AD%E3%83%BC,%E6%A8%AA%E3%81%AB%E5%88%86%E5%89%B2%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82 GNU Screenコマンドをつかってみる #screen - Qiita]
[https://qiita.com/SAITO_Keita/items/b79ebc5af64aad28fc4a#:~:text=%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E7%8A%B6%E6%85%8B%E3%81%A7%E3%82%AD%E3%83%BC,%E6%A8%AA%E3%81%AB%E5%88%86%E5%89%B2%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82 GNU Screenコマンドをつかってみる #screen - Qiita]


288行目: 315行目:
** C-a X/Command:remove=現在のRegionを終了。
** C-a X/Command:remove=現在のRegionを終了。
** C-a Q/Command:Only=現在以外のRegionを終了。
** C-a Q/Command:Only=現在以外のRegionを終了。
===== .screenrc =====
====== スタートアップメッセージ ======
startup_message off
====== スクロール ======
[https://www.robotech-note.com/entry/2017/01/27/082929 linux screen中にマウスホイールでスクロールする方法 - 技術メモ集]
デフォルトだとマウススクロールなどに対応していない。以下の設定で対応でき、通常使用で問題なくなる。
termcapinfo xterm* ti@:te@
defscrollback 100000
=== Binary ===
==== .so ====
ソフトウェアの依存関係などの調査で.soファイルの分析を行うことがある。
[https://zenn.dev/nyoho/scraps/3651de0bd0b313 .soファイルの中のシンボル探し]
* nm
* ldd
* string


== Coding ==
== Coding ==
439行目: 489行目:


フレームワークの中にライブラリーも含めていいと思う。
フレームワークの中にライブラリーも含めていいと思う。
「[https://webbigdata.jp/what-is-ai/page-6804/page-8359/page-12091/ Pythonのモジュールとパッケージとライブラリとフレームワークの違い]」がわかりやすい。
フレームワークはライブラリーを含んでいる。ライブラリーで共通でいいと思う。


==== Category ====
==== Category ====
622行目: 676行目:
=== Tool ===
=== Tool ===
https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628
https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628
[https://www.quora.com/What-are-the-best-UML-tools-for-macOS What are the best UML tools for macOS? - Quora]


* デスクトップ
* デスクトップ
627行目: 683行目:
** ArgoUML
** ArgoUML
** UMLet
** UMLet
** OmniGraffle
** edraw: 有料。
** Umbrello
** Modelio
* クラウド
* クラウド
** Visual Paradigm
** Lucidchart: 有料。
** Lucidchart: 有料。
** Creately: 有料。
** Creately: 有料。
** diagrams.net: モデルじゃない。
** diagrams.net: モデルじゃない。
*その他
**PlantUML


UmbrelloとModelioはそれらと比較して何がよかったのだっけ?
UmbrelloとModelioはそれらと比較して何がよかったのだっけ?
Eclipse Papyrusが動作するならこれがいい。Eclipseは安定しているから、これのプラグインで動作するなら信頼できるだろう。
papyrusは一度試してダメだった気がするが。


=== Umbrello ===
=== Umbrello ===
650行目: 717行目:
* 関連: 実線矢印。メソッド内インスタンスなど。
* 関連: 実線矢印。メソッド内インスタンスなど。
* 依存: 点線矢印。引数やローカル変数、返却値。
* 依存: 点線矢印。引数やローカル変数、返却値。
=== Papyrus ===
[https://eclipse.dev/papyrus/download.html Papyrus Dowloads]
[https://eclipse.dev/papyrus/documentation.html Papyrus Documentation]
==== Tutorial ====
公式の[A slide-ware tutorial on Eclipse Papyrus usage for starters (2010-10-01)]を参考に基本的な使い方を学ぶ。
[File]-[New]-[Papyrus prooject]
これでプロジェクトを作ると、以下が [Project Explorer] に作られる。
* <project name>
** <project name>
*** di: ツールメタデータ。モデル作成のエントリーポイント。
*** notation: 画像データ。
*** uml: UMLモデルデータ。
このdiをダブルクリックして描画を開始する。
1個のプロジェクトでいろんな図に対応していて、モデルを流用できる形になっている。悪くない。これを使う。


=== Design ===
=== Design ===
1,188行目: 1,277行目:
凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。</blockquote>
凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。</blockquote>


== VCS ==
== Shell ==


=== List ===
=== Shell Command Language ===
Comparison of issue-tracking systems - Wikipedia <nowiki>https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems</nowiki>


BTS。GitHubみたいな。PHP製の以下がよさそう。
==== Compound Commands ====
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_09_04 Shell Command Language]


* Tuleap
===== Case Conditional Construct =====
* Phabricator/Phorge: 共用サーバー不能。
case word in
* MantisBT
    [(]pattern1) compound-list;;
* FusionForge
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
* GLPI
    [[(]pattern[ | pattern] ... ) compound-list]
* Faveo Helpdesk
esac
* [https://sourcehut.org/ sourcehut - the hacker's forge]: Python製。FSF推奨。
* Fossil


VCSとの統合状況がまちまち。
* 未マッチで終了ステータス0。
* pattern部分: シェル展開が有効。他はglob。
* |でOR検索相当。
* 最後のパターンの;;は省略可能。if文のようにも使える。
* 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。


phorgeがダメだったので、Mantis/Fossil/sourcehutあたりが共用サーバーで検討可能か。
BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。


https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
=== ワイルドカード ===
ワイルドカードで.始まりのファイルをマッチさせたい。


他に以下がある。
以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
echo {.*,*}


* Gitea
=== BOM ===
* Cgit
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]
* Gitlab
* SourceHut: Python
* GitBucket: Java


Gitlabは共用サーバーで可能なのか?無理。cgitの他、gogsもある?
ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。


CGIで利用可能なもの。
=== awk ===
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ The Open Group Base Specifications Issue 7]


* Cgit: gitの出力を見れるだけ。issueはない。
==== 変数 ====
* Gitweb: cgit同様。
* ViewGit:
* Kallithea: 有力。[https://kallithea-scm.org/ Kallithea]。WSGI。CGI未対応。
他に。


* rhodecode: CGIではない。Python+WSGI
===== 特別 =====
* [[wikipedia:Category:Project_management_software|Category:Project management software - Wikipedia]]
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


[https://jp.quora.com/Python%E3%81%AF%E4%BA%BA%E6%B0%97%E3%81%AE%E8%A8%80%E8%AA%9E%E3%81%A7%E3%81%99-%E3%81%97%E3%81%8B%E3%81%97-%E3%81%9D%E3%81%AE%E5%89%B2%E3%81%ABPython%E3%81%8C%E6%B0%97%E8%BB%BD%E3%81%AB%E5%88%A9%E7%94%A8%E3%81%A7 Pythonは人気の言語です。しかし、その割にPythonが気軽に利用できるレンタルサーバーは少ない感じがします。何故、レンタルサーバーはPythonの利用に消極的なのですか? - Quora]」にあるように、WSGIをCGIにすることもできるがいまいちらしい。
===== スコープ =====
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


他。
関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。


https://chatgpt.com/c/67546eda-20ac-800b-b37f-7e8954c128f5
==== 文/statement ====


* GNU Savannah/savane
* actions
* Bugzilla: 課題管理のみ。
** if/else
* Trac: CGI OK。
** while/do...while/for
* Roundup ([https://roundup.sourceforge.io/ Roundup Issue Tracker - Roundup 2.4.0 documentation]): 課題管理のみ?
** break/continue
* Debbugs
** delete
** next
** exit
* output
** print
** printf


savaneはメンテナンスされていないので、Trac一択。redmineはCGIで動作しない。
==== 関数 ====


=== Git ===
===== 組込関数 =====


==== Commit ====
* Arithmetic
 
** atan2
===== マージコミット後のコミット追加 =====
** cos
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。
** sin
 
** exp
git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
** log
 
** sqrt
しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。
** int
 
** rand
===== コミットオプション =====
** srand
[https://git-scm.com/docs/git-commit Git - git-commit Documentation]
* String
 
** gsub
コミットメッセージ指定のためのオプションがある。
** index
 
** length
* -m|--message <message>: コミットを文字列で指定。複数指定可能で、その場合段落で区切ってくれる。2行目以後を書きたい場合などで使う。
** match
* -C|--reuse-message <commit>: 指定したコミットのコミット情報を再使用する。
** split
* -c|--reedit-message <commit>: -Cの同じだが、編集画面を表示してコミットメッセージを編集して再使用する。
** sprintf
* -F|--file=<file>: 指定したファイルをコミットメッセージに使う。-を指定すると標準入力を使う。
** sub
 
** substr
基本は-m。-mの複数指定。
** tolower
 
** toupper
===== 過去コミットのメールアドレスの変更 =====
* I/O
 
** close
* [https://www.git-tower.com/learn/git/faq/change-author-name-email How can I change the author (name / email) of a commit? | Learn Version Control with Git]
** getline
* [https://zenn.dev/flyingbarbarian/articles/241627cae5988a Gitのcommitの名前やメールアドレスを過去からまとめて変更する]
** system


単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
print/printfは関数ではなく、statement/文扱い。
git commit --author="John Doe <john@doe.org>"
--amendと併用することで、過去コミットも変更できる。


数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。
==== ヘッダー出力、列別最大長さ出力。 ====
<nowiki>awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv</nowiki>


===== 第一コミットの変更 =====
==== CSV ====
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
# csvparser.awk


* [https://dev.classmethod.jp/articles/git-rebase-from-root/ [Git] 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
## Usage
* [https://git-scm.com/docs/git-rebase Git - git-rebase Documentation]
# awk -f csvparser.awk data.csv


通常、第一コミットはammend以外では変更できない。
# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
 
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
rebase --root [branch] でブランチの第一コミットも参照して改変可能。
function callback(row, len, fields,  col, field) {
 
    for ( col = 1; col <= len; col++ ) {
===== マージコミットの打ち消し =====
        field = fields[col]
マージコミットは扱いがやや特殊。
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
git revert -m 1 マージコミット
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
git reset --hard HEAD~1 # マージコミット前
        print row ":" col " " field
どちらか。
    }
 
}
==== stash ====
 
===== 復元 =====
[https://qiita.com/generosity-naman/items/237338f8fe5b7e3b9a76 Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita]


git stash drop実行時に、削除したコミットのSHA1が表示される。
BEGIN { row = max_idx = 0 }
 
{
そのSHA1をapplyで指定すれば、取り込める。
    idx = 0
git stash apply [stash_hash]
    sub(/\r$/, "")
 
    while ($0 != "") {
===== リモート =====
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
[https://qiita.com/mather314/items/a1536c52a2eb0426b2b5 gitの不要なブランチを消すコマンド #Git - Qiita]
            fields[++idx] = ""
git fetch -p/--prune
        } else if (match($0, /^["]/)) {
リモートの削除済みブランチをローカルに同期する。
            fields[++idx] = substr($0, 2)
 
            for (;;) {
===== リモートの最新タグ =====
                if (getline == 0) exit 1
https:/stackoverflow.com/questions/20734181/how-to-get-list-of-latest-tags-in-remote-git
                sub(/\r$/, "")
 
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
git ls-remote --tag --sort=taggerdate
                gsub(/["]["]/, "\"")
 
                fields[idx] = fields[idx] "\n" $0
date関係のsortはオブジェクトへのアクセスが必要なので、ローカルにないとダメとか。
            }
 
            fields[idx] = fields[idx] "\n"
https:/git-scm.com/docs/git-ls-remote.html
        } else {
 
            exit 1
https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning
        }
 
        field = substr($0, RSTART, RLENGTH)
git rev-listでいけそう。
        $0 = substr($0, RSTART + RLENGTH)
 
        lastcomma = sub(/,$/, "", field) > 0
https:/gist.github.com/rponte/fdc0724dd984088606b0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
 
        fields[idx] = fields[idx] field
===== 差分ファイル抽出 =====
    }
情報源: [https://qiita.com/kaminaly/items/28f9cb4e680deb700833 gitで差分ファイルを抽出する #Git - Qiita]
    if (lastcomma) fields[++idx] = ""
 
    while (idx < max_idx) delete fields[max_idx--]
git archiveとgit diffを組み合わせる。
    callback(++row, idx, fields)
git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip
    max_idx = idx
ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。
}
 
git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?
 
例:
mkdir -p archive
git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/


===== core.autocrlf =====
</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
<blockquote>warning: in the working copy of 'docker/README.md', LF will be replaced by CRLF the next time Git touches it</blockquote>Windowsでは改行にCR+LFを使うが、mac/LinuxはLFのみ。これの違いの処理のための設定がcore.autoclrlf
tail -c +4 data/101543.csv | awk -f csvparser.awk


* true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
=== Other ===
* false=変換しない。
* input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。


わかりにくい。基本はfalseで良いと思われる。
==== binary ====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]


===== gitkの文字化け対策 =====
バイナリーデータの読込はodコマンド。なければhexdump。
[https://www.pistolfly.com/weblog/2010/02/gitk.html gitkのエンコーディングを設定する - Pistolfly]


gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
書込はprintf。
git config --global gui.encoding utf-8


===== ファイル名などの文字化け対策 =====
head/tailの-cはPOSIXで使えたか?
[https://qiita.com/kumazo/items/2169e1ee7be278f82b94 Git for Windows で日本語を使いたい #Vim - Qiita]
git config --global core.quotepath false
git config --global gui.encoding utf-8


===== 改名と修正 =====
==== root ====


* [https://qiita.com/yukimura1227/items/fbb076db61a2e43a32e3 gitでrename&modifyしたファイルのログを追跡できるようにしたい場合 #Git - Qiita]
===== リダイレクト出力 =====
* [https://zenn.dev/yoichi/articles/how-git-handles-renaming Gitはファイルのリネームをどう扱うか]
[https://blog.shaba.dev/posts/redirect-with-sudo sudo権限でリダイレクト処理を行ってファイルに書き込む方法]


改名と修正を同時にすると、改名を検知できない。
リダイレクトはログインユーザーの権限でなされるらしく、root権限のある場所にファイル出力できない。


-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。
teeコマンドでやる。
pwd | sudo tee out.dat
teeコマンド実行する側でsudoが必要。


===== 差分無視 =====
[https://qiita.com/odekekepeanuts/items/8a056b87c9e481e07e57 git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita]
==== ログインシェルの確認 ====
[https://docs.oracle.com/cd/E19683-01/816-3946/customize-89075/index.html 第 10 章 動作環境のカスタマイズ (Solaris ユーザ]
ログインシェルはGUIログインでも内部的にある。ログインシェルが読みこむprofileファイルなどは、ログイン時に、1回だけ実行したい処理の記述場所として最適。
SHELL環境変数にログインシェルのパスが入っている。
echo $SHELL
/bin/bash
==== OSの判別 ====
OSTYPE環境変数に値があるのでこれで判別する。
例えば以下の値が入っている。
linux-gnu
darwin23
これらを検知して判定する。
case $OSTYPE in
  linux*) echo 'linux';;
  darwin*) echo 'Mac';;
esac
==== Configure ====
===== profile =====
[https://blog1.mammb.com/entry/2019/12/01/090000 bash の初期化ファイル .profile, .bashrc, .bash_profile の使い分けと管理方針 - A Memorandum]
環境変数など~/.profileに全部のシェルの共通設定を記述して、~/.bash_profileなどのログインシェルやbashrcなどで参照するのがいい。


-wでインデント違いを無視してくれる。
== cmd.exe ==


===== squash =====
=== Control block ===
squashすると、squash対象コミットが、対象の直前のコミットに含められる。


===== gitignore =====
==== for ====
[https://git-scm.com/docs/gitignore/en Git - gitignore Documentation]
あくまでコマンド。


====== Format ======
===== nest =====
記述方法を整理する。


* 空行は無視。
* [https://chicagopile1-75.hatenablog.com/entry/2018/05/23/143502 バッチファイルで2重ループ - ハムスターに飼われる院生のブログ]
* #始まりの行はコメント扱い。
* 終端スペースは無視。
* !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
* /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
** 先頭と中間の/は相対パスを意味する。
** それ以外、末尾の//なしの場合、現在以下のディレクトリーにもマッチする。
** 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
* *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
* **は特殊な意味がある。
** **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
** /**=配下のすべてにマッチ。
** a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。


後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
* [https://web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/ web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/]


反転の!と/の扱いに特に注意が必要。
ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。


先頭スラッシュをつけないと、再帰的になる。
=== bitsadmin ===
    $ cat .gitignore
Windowsでのファイルダウンロードコマンド
    # ディレクトリ foo/bar 以外のすべてを除外
    /*
    !/foo
    /foo/*
    !/foo/bar


====== 空ディレクトリーの維持 ======
Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
[https://stackoverflow.com/questions/115983/how-do-i-add-an-empty-directory-to-a-git-repository How do I add an empty directory to a Git repository? - Stack Overflow]


gitは空ディレクトリーを履歴管理できない。何かファイルが必要。
書式:
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
=== certutil ===
!.gitignore
Windowsでのハッシュの確認に使える。
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。
  certutil -hashfile file
 
====== 指定ファイルのみ除外 ======
*
  !.gitignore
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。


===== gitattributes =====
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
[https://git-scm.com/docs/gitattributes Git - gitattributes Documentation]
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。
=== rlogin.cmd ===
コマンドキーの送信を自動化できる?
rem rlogin.cmd
@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%


* text
=== 実行中プロセスのパスの確認 ===
* eol
出典: [https://superuser.com/questions/768984/show-exe-file-path-of-running-processes-on-the-command-line-in-windows Show EXE file path of running processes on the command-line in Windows - Super User]。
* working-tree-encoding
wmic process get ProcessID,ExecutablePath
* ident
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
* filter
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST
* diff
* merge
* conflict-marker-size
* whitespace
* export-ignore: git archiveなどに含めないことをマーク。
* export-subst
* delta
* encoding


===== ファイルのインデックスのみ削除 =====
=== 簡易編集モード/挿入モード ===
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
git rm --cached


==== gitk ====
* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


===== problem =====
Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
ブランチ名が長いと、右クリックしにくい


==== submodule ====
cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
https://git-scm.com/docs/git-submodule


https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB
そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。


===== foreach =====
[□挿入モード] にすると回避できる模様。
サブモジュールの全部を一括処理する。
foreach [--recursive] <command>
<command>部分では$sm_pathでパスを参照できる。
git submodule foreach 'echo $sm_path `git rev-parse HEAD`'


Entering 'XXX'
== Web ==
XXX hash
submoduleの中に入ってから実行することに注意する。


便利なコマンド。
=== URL ===
git submodule foreach 'git reset --hard'


==== Other ====
==== クエリー配列 ====


===== 他のブランチとの同一化 =====
* [https://shinkufencer.hateblo.jp/entry/2019/05/18/163912 クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩]
git diff HEAD master | patch -p 1
* [https://qiita.com/s4kd0R/items/8a11d88099008bb1e9dc PHPでクエリパラメータから配列を受け取る物語 #JavaScript - Qiita]
patchの他にgit applyでもいい。
* [https://www.php.net/http_build_query PHP: http_build_query - Manual]


===== .netrc =====
やり方がいくつかある。
https://social.senooken.jp/conversation/1573147#notice-2217499


Gitのパスワード入力の省略方法に~/.netrcがある。
# CSV文字列で受取後分割: <nowiki>https://www.sakdor.net/test/?var=1,2,3</nowiki> explode(",",$_GET[var]);
# 配列添字
## http://www.sakdor.net/test/?var&#x5B;&#x5D;=1&var&#x5B;&#x5D;=2&var&#x5B;&#x5D;=3
## http://www.sakdor.net/test/?var&#x5B;a&#x5D;=1&var&#x5B;b&#x5D;=2&var&#x5B;c&#x5D;=3
## http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3


しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。
データが決まっているならcsvがシンプル。


In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink
==== CGI ====
https://chatgpt.com/c/67634332-a3b8-800b-87a2-e21bd21a1cfc


せのお (妹尾 賢)せのお (妹尾 賢) in reply to
WordPressなどのWebアプリだとファイル拡張子が登場しない。これはいくつかの仕組みが組み合わさって実現されている。


理由が分かった。
# '''パーマリンク設定''' によるクリーンなURL構造の生成。
# '''.htaccess(Apache)''' や '''リライトルール''' によるURLの書き換えとルーティング。
# '''index.php''' を起点とする動的な処理。
# '''テンプレート階層''' に従って適切なPHPファイルを呼び出す。


1. Gitはhttpとhttpsの通信にcURLを使っている。
.htaccessでindex.phpにリダイレクトして、index.phpから全て処理している。これにより省略できている。


<nowiki>https://github.com/git/git/blob/master/INSTALL#L141</nowiki>
同じ用に、アプリ側が対応していれば、index.fcgiに全部リダイレクトして、パスを解釈してくれるなら、/でのアクセスもできる気がする。


2. cURLが.netrcにも対応しているから。
[https://stackoverflow.com/questions/36405496/how-can-i-run-a-fastcgi-script-in-root-url-without-path apache - How can I run a FastCGI script in root url (/ - without path)? - Stack Overflow]


<nowiki>https://ec.haxx.se/usingcurl-netrc.html</nowiki>
=== HTTP ===
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]


=== GitHub ===
==== Content-Disposition ====
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


==== Account ====
[https://datatracker.ietf.org/doc/html/rfc6266 RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)]
  Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
Content-Disposition: inline
ユーザー名は、英数字と-のみが使用可能。
Content-Disposition: attachment
  Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。


組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。
==== multipart/form-data ====
rfc7578


=== Fossil ===
* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
* [https://gigazine.net/news/20231231-why-sqlite-does-not-use-git/ SQLiteがバージョン管理システムとしてGitを採用しない理由 - GIGAZINE]
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]
* [https://gigazine.net/news/20201229-fossil/ GitとGitHubの機能をひとつのバイナリに詰め込んだ「Fossil」レビュー - GIGAZINE]


外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。
ファイルアップロード用のMIME type。


[https://fossil-scm.org/home/doc/trunk/www/index.wiki Fossil: A Coherent Software Configuration Management System]
リクエストヘッダー
 
Content-Type: multipart/form-data; boundary=--hogehoge
いくつか癖があるので注意する。
リクエストボディー
 
--hogehoge
https://chatgpt.com/c/674e38de-a8c0-800b-8991-e0d68a2f0d86
Content-Disposition: form-data; name="user_name"
 
Content-Type: text/plain
複数のリポジトリーを取り扱うことは可能。ただし、Web UI上からリポジトリーの新規作成はできない。リポジトリーの新規作成はあくまでコマンドラインから行う必要がある。ここは集中的。
test
--hogehoge
Content-Disposition: form-data; name="email"
sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"
male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg
\xff\xd8\....
--hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。


[https://okamerin.com/nc/title/508.htm git と fossil の比較 git vs fossil-scm | タイトル]
[https://weblabo.oscasierra.net/curl-post/ curlコマンドでPOSTする, 様々な形式別メモ |]


完全に個人なら悪くないが、コマンドの操作体系も異なるし、ややリスクがある。Tracのほうが無難。
curlでの送信理由。


==== Install ====
-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
curl -X POST -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
データとテキストを同時送信したい場合、-Fで複数指定する。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
curlだと上記のboundaryなどをうまくやってくれるのだと思う。


===== Binary =====
リクエストボディー全体をファイルデータにする場合。
[https://fossil-scm.org/home/doc/trunk/www/index.wiki Fossil: A Coherent Software Configuration Management System]
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>


ソースコードからコンパイルするか、コンパイル済みバイナリーを配置するだけ。
=== IP address ===
VER=2.25
出典: [https://glocalnet.jp/vpn/topix/archives/67#:~:text=%EF%BC%94%EF%BC%8E%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%20%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%AF%E4%B8%BB%E3%81%AB3%E3%81%A4%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,%E3%83%BB%E5%A5%91%E7%B4%84%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%81%A7%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%20%E3%83%BB%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8BSIM%E3%82%92%E5%A5%91%E7%B4%84%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%20%E3%83%BBVPN%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%8F%90%E4%BE%9B%E4%BC%9A%E7%A4%BE%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット]
mkdir -p ~/.local/stow/fossil-$VER ~/.local/bin
cd ~/.local/stow/fossil-$VER
curl -O [https://fossil-scm.org/home/uv/fossil-linux-x64-2.25.tar.gz https://fossil-scm.org/home/uv/fossil-linux-x64-$VER.tar.gz]
tar -xf fossil-$VER.*
ln -fns ../stow/fossil-$VER/fossil


===== Server =====
自宅サーバーを行う際、固定IPアドレスが必要になる。
[https://fossil-scm.org/home/doc/tip/www/server/any/cgi.md Fossil: Serving via CGI]


CGIで実行するにはいくつか手順がある。
取得方法がいくつかある。


CGIディレクトリーに以下の内容のCGIスクリプトを用意する。
* 契約しているプロバイダでオプションとして申し込む方法
#!/usr/bin/fossil
* 固定IPアドレスに対応しているSIMを契約する方法
repository: /home/fossil/repo.fossil
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''
repositoryの部分は指定方法がいろいろある。単一リポジトリーのホストなら上記でいいが、複数のリポジトリーを取り扱いたければ、リポジトリー群の格納ディレクトリーをdirectory: で指定する。


また、リポジトリーが不在の場合のリダイレクト先を指定するnotfound:もある。
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
#!/usr/bin/fossil
directory: /home/fossil/repos
notfound: <nowiki>http://url-to-go-to-if-repo-not-found/</nowiki>
CGIスクリプトをcgi-bin/repoとした場合、展開後は [http: //mydomain.org/cgi-bin/repo/XYZ] のようなURLで [/home/fossil/repos/XYZ.fossil] にアクセス可能。


CGIで展開されると。
=== Authentication ===
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。


fossil.cgiにする。
==== Basic認証 ====
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。


https://chatgpt.com/c/674e38de-a8c0-800b-8991-e0d68a2f0d86
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


fossilのweb uiではリポジトリーの新規作成ができない。新規作成だけはコマンドラインから行う必要がある。これだけがいまいち。保留。
[https://dev.classmethod.jp/articles/delete-cache-for-basic-authentication/ Basic認証のキャッシュを削除する(ログアウトする) | DevelopersIO]
=== Phorge ===
[https://we.phorge.it/ Home]


PhorgeはPhabricatorのフォーク。
ログアウト時は、hoge@domainのようにパスワードを省略した任意のユーザー名でログインを試みて既存のログイン状況を上書きする模様。


==== About ====
Digest認証も共通。


===== Introduction =====
==== Digest認証 ====
[https://we.phorge.it/book/phorge/article/introduction/ ◉ Introduction]
[https://qiita.com/Threen/items/409971705767e2f89fb2 Basic認証・Digest認証・Form認証をざっくり理解 #Security - Qiita]


以下が主な機能。
HTTP標準の認証。Basic認証とほぼ同じ。ただし、パスワードをハッシュ化している。そのため、DBのパスワードが流出した場合に比較的安全。


* コードレビューツール=Differential
==== OAuth ====
* リポジトリーブラウザー=Diffusion
Ref
* バグトラッカー=Maniphest
* ウィキ=Phiriction


GitHubの自己ホスト。
* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]


===== Phabricator =====
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
[[wikipedia:Phabricator|Phabricator - Wikipedia]]


PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。
以下が登場人物。


主なユーザー。
* resource owner: あるサイトのユーザー。
* resource server: あるサイトのユーザーのデータの保有サーバー。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


* AngularJS
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
* Discord
* Facebook


==== Install ====
処理の流れ。


* [https://we.phorge.it/book/phorge/article/installation_guide/ ◉ Installation Guide]
# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
* [https://ipv6.rs/tutorial/Ubuntu_Server_Latest/Phorge/ Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest]
# client<-resource owner: Authorization Grant。
* https://chatgpt.com/c/6749041b-a1b4-800b-a134-96a8029c086e
# client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
# client<-authorization server: Access Token
# client->resource server: Access Token。アクセストークンでアクセス。
# client<-resource server: Access Token


===== Requirement =====
Consumer Key/Secret: アプリ識別用のID/PW。
LAMP環境で動作する。


共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。
Access Token: サイトにアクセスするためのパスワード。


* MySQL: 5.5以上。
=== API ===
* PHP 7.2以上
* git: 2.5.0以上。
* PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl


ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。
==== 複数レコードの登録 ====
[https://buddypia.com/2021/11/14/%E8%A4%87%E6%95%B0%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89api%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F%E8%A9%B1/ 複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ]


===== Download =====
既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
以下のコマンドで取得する。
$ cd somewhere/ # pick some install directory
somewhere/ $ git clone <nowiki>https://we.phorge.it/source/arcanist.git</nowiki>
somewhere/ $ git clone <nowiki>https://we.phorge.it/source/phorge.git</nowiki>
gitの設定。
$ sudo git config --system --add safe.directory somewhere/arcanist
$ sudo git config --system --add safe.directory somewhere/phorge
phorge用のDBを作っておく。
cp /var/www/html/phorge/phabricator/conf/local/local.json.example /var/www/html/phorge/phabricator/conf/local/local.json


"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"
[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
後は開くだけ。


実操作。
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。


こういうディレクトリー構成想定。
==== パラメーター ====
public_html
[https://stackoverflow.com/questions/25385559/rest-api-best-practices-args-in-query-string-vs-in-request-body json - REST API Best practices: args in query string vs in request body - Stack Overflow]
+ phorge.gnusocial.jp 公開ディレクトリー。
+ phorge phorge関係の格納場所。
  + phorge
  + arcanist
取得。
TAG=2024.35
mkdir phorge
cd phorge
PKG=phorge
git clone --depth 1 [https://we.phorge.it/source/phorge.git https://we.phorge.it/source/$PKG.git]
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..
PKG=arcanist
git clone --depth 1 [https://we.phorge.it/source/arcanist.git https://we.phorge.it/source/$PKG.git]
cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..


git config --add safe.directory arcanist
パラメーターの指定に3種類ある。
git config --add safe.directory phorge
phorge/webrootが公開ディレクトリーになるので、これをシンボリックリンクで公開ディレクトリーにリンクする。
DOMAIN=phorge.gnusocial.jp
ln -fns phorge/phorge/webroot ../$DOMAIN
「[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]」に記載のあるリダイレクト設定をする。


以下相当の設定を行う。
# リクエストボディー
<VirtualHost *>
# クエリー
  # Change this to the domain which points to your host.
# パス
  ServerName phorge.example.com
  # Change this to the path where you put 'phorge' when you checked it
  # out from the upstream when following the Installation Guide.
  #
  # Make sure you include "/webroot" at the end!
  DocumentRoot /path/to/phorge/webroot
  RewriteEngine on
  RewriteRule ^(.*)$          /index.php?__path__=$1  [B,L,QSA]
</VirtualHost>
<Directory "/path/to/phorge/webroot">
  Require all granted
</Directory>
具体的には、phorge/webroot/.htaccessに以下を記載して、ファイルがなければ作成する。
cat >phorge/webroot/.htaccess <<-'EOT'
RewriteEngine on
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
EOT
上記設定後phorge.gnusocial.jpにアクセスすると以下のエラーになる。
Request parameter '__path__' is not set. Your rewrite rules are not configured correctly.


* [https://stackoverflow.com/questions/25368612/phabricator-rewrite-rules-configuring-issue apache - Phabricator rewrite rules configuring issue - Stack Overflow]
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
* [https://stackoverflow.com/questions/49344737/phabricator-install-rewrite-rules-are-not-configured-correctly php - Phabricator install. Rewrite rules are not configured correctly - Stack Overflow]


上記が少し参考になる。require指令を指定していないのが問題。
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。


うーん。この問題を解決できない。調べても解決例が出てこない。断念する。他のソフトにする。
この原則に従うとシンプルだろう。


===== Config =====
* URIには長さの制限がある。
[https://we.phorge.it/book/phorge/article/configuration_guide/ ◉ Configuration Guide]
* ボディー
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


以下のコマンドでユーザーを認識させる。
==== 検索機能のGET/POST ====
phorge/ $ ./bin/storage upgrade --user <user> --password <password>


==== Diffusion ====
* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]


===== Hosting =====
検索機能にGETとPOSTのどちらを使うか?という議論がある。
[https://we.phorge.it/book/phorge/article/diffusion_hosting/ ◉ Diffusion User Guide: Repository Hosting]


=== Kallithea ===
データ登録するわけなじゃないのだから、GETがいいんじゃない?
[https://kallithea-scm.org/ Kallithea]


https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。


Python 3.6でCGIでも動作する管理ソフト。
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。


[https://kallithea.readthedocs.io/en/stable/index.html Kallithea Documentation — Kallithea 0.7.0 documentation]
ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。


紹介: [https://www.farend.co.jp/blog/2015/08/kallithea/ GitとMercurialに対応のリポジトリ管理ツール「Kallithea」 - ファーエンドテクノロジー株式会社]
==== レート制限対策 ====


==== Administrator guide ====
* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
* [https://keirinomikata.zendesk.com/hc/ja/articles/4404549985945-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E6%95%B0%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E9%99%90%E3%81%AE%E5%AF%BE%E7%AD%96%E6%96%B9%E6%B3%95 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


===== Installation on Unix/Linux =====
いろいろ方法がある。
[https://kallithea.readthedocs.io/en/stable/installation.html Installation on Unix/Linux — Kallithea 0.7.0 documentation]


====== ディレクトリー構造 ======
* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
* 配列を利用して、1回のリクエストでまとめて取得する。
/var/www/kallithea/
* インターバルを設ける。
├── config/                  # 設定ファイルやシークレットを保存
* HTTP 429/413を検知して、リトライする。
│  └── kallithea.ini        # Kallitheaのメイン設定ファイル
├── data/                    # データベースや一時ファイル用ディレクトリ
│  ├── db.sqlite            # SQLiteの場合のデータベースファイル
│  └── sessions/            # ユーザーセッションデータ
├── logs/                    # ログファイル保存ディレクトリ
│  └── kallithea.log        # メインのアプリケーションログ
├── repos/                  # Git/Mercurialリポジトリを保存するディレクトリ
│  ├── project1.git/        # プロジェクト1のGitリポジトリ
│  └── project2.hg/        # プロジェクト2のMercurialリポジトリ
├── static/                  # 静的ファイル(JavaScript, CSS, 画像など)
│  ├── css/
│  ├── js/
│  └── img/
└── venv/                    # Python仮想環境
    ├── bin/
    ├── lib/
    └── ...
static配下が公開ディレクトリー。共用サーバーの場合。public_htmlにkallitheaとkallithea.domainでシンボリックリンクでやるとよさそう。


====== Installing a released version in a virtualenv ======
==== 指数関数的バックオフ ====
いくつか方法があるが、virtualenvが推奨されている。


coreserver v1のpythonはpython 3.6だった。
* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
cd public_html/
* [[wikipedia:Exponential_backoff|Exponential backoff - Wikipedia]]
DOMAIN=kallithea.gnusocial.jp
* [https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja 指数バックオフ  |  Memorystore for Redis  |  Google Cloud]
cd $DOMAIN
* [https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/cloud-design-patterns/retry-backoff.html バックオフパターンで再試行 - AWS 規範ガイダンス]リトライ時は以下のアルゴリズムがいいらしい。
python3 -m venv venv
wait_interval = base * 2^n +/- jitter
python3 -m venv venvの実行時に以下のエラー。
Error: Command '['/virtual/senooken/public_html/kallithea.gnusocial.jp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 2.
[https://qiita.com/sin9270/items/7a17d21ccd7c2531ac41 cimg/pythonでvenvによる仮想環境の作成がエラーになる #Python - Qiita]


pipが見つからないのが原因の模様。--without-pipでインストールして、仮想環境内にpipを直接インストールする。
* <code>wait_interval</code> は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
python3 -m venv --without-pip venv
* <code>base</code> は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
. venv/bin/activate
* <code>n</code> は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、<code>n</code>の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
curl https://bootstrap.pypa.io/pip/<nowiki>$(python3 -V | grep -o '[0-9].[0-9]')/get-pip.py -o get-pip.py</nowiki>
* <code>jitter</code> は 0 から <code>base</code> の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し <code>wait_interval</code> の合計に加算するか減算するか、ランダムで選択してください。
python3 get-pip.py
pip install --upgrade pip
OK。以下のコマンドで基本要件を確実にする。
pip install --upgrade pip "setuptools<67"
Kallitheaをインストール。
pip install --upgrade kallithea
なんかエラーが出る。
  ERROR: Command errored out with exit status 1:
    command: /virtual/senooken/public_html/kallithea.gnusocial.jp/venv/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/setup.py'"'"'; __file__='"'"'/export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /export/tmp/pip-pip-egg-info-kjtbdngw
        cwd: /export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/
  Complete output (3 lines):
  /usr/lib64/python3.6/distutils/dist.py:261: UserWarning: Unknown distribution option: 'convert_2to3_doctests'
    warnings.warn(msg)
  error in FormEncode setup command: use_2to3 is invalid.
  ----------------------------------------
WARNING: Discarding <nowiki>https://files.pythonhosted.org/packages/2f/53/707c2b9b65ea6bedde67c21cbf7c71394f4a198620d4e9c1771214b91dcc/FormEncode-1.3.1.tar.gz#sha256=ada2f51792b1b484e5bb7b6cc14acfc1bc11fafc967cf015cd57e856053ca7f6</nowiki> (from <nowiki>https://pypi.org/simple/formencode/</nowiki>). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
Collecting kallithea
[error in FormEncode setup command: use_2to3 is invalid.]


[https://qiita.com/nkmr_RL/items/85edc2ee68c01ec5582e 急にpip installで一部のライブラリのインストールが失敗するようになった件 #Python3 - Qiita]
==== バックエンドとフロントエンドの分離 ====
https://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45


setuptoolsを58.0.0未満にすればいいらしい。
SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。
pip install setuptools==57.4.0
この実行後pip install --upgrade kallitheaが成功。


====== Prepare front-end files ======
SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。
以下のコマンドでフロントエンドを用意。
kallithea-cli front-end-build
事前にnpmが必要な模様。
FileNotFoundError: [Errno 2] No such file or directory: 'npm': 'npm'
npmをインストールしたら解決。


===== Setup =====
SSRの利点。
[https://kallithea.readthedocs.io/en/stable/setup.html Setup — Kallithea 0.7.0 documentation]


====== Setting up a Kallithea instance ======
* SEO
まず以下のコマンドでmy.iniを作成する。
* 初期表示。
kallithea-cli config-create my.ini http_server=waitress
* 匿名。
http_serverのところで使用するHTTPサーバー種別を指定する。waitress, gearbox, gevent, gunicorn, or uwsgi.を指定可能。


ひとまずデフォルトのこれで。
SSRの課題。


続いてDBを作成する。PostgreSQL/SQLIte/MariaDB/MySQLに対応。最初はSQLiteを使用しておいて、後で他のDBへのアクセスが推奨されている。
* サーバー負荷: データとHTML作成を同時に行うから。
* 分散困難:


が、共用サーバーだと書き込みでプロセス削除されると嫌なので最初からMariaDBにする。まず以下のコマンドでドライバーを取得。
キャッシュの活用がポイントになるとのこと。
  pip install mysqlclient


  OSError: mysql_config not found
=== Network ===
mariadbは違う模様。以下の開発パッケージが必要らしい。
  sudo apt-get install libmysqlclient-dev
不明。一旦スキップ。


SQLite以外を使う場合、my.iniでsqlalchemy.urlのコメントアウトを解除してDBのユーザー名とパスワードを記入しておく。
==== ssh ====
#########################
##      DB CONFIG      ##
#########################
#sqlalchemy.url = sqlite:///%(here)s/kallithea.db?timeout=60
#sqlalchemy.url = postgresql://kallithea:password@localhost/kallithea
#sqlalchemy.url = mysql://kallithea:password@localhost/kallithea?charset=utf8mb4
sqlalchemy.url = mysql://[username]:[password]@localhost/kallithea?charset=utf8mb4
## Note: the mysql:// prefix should also be used for MariaDB
用意したら以下のコマンドで初期テーブルを作成する。
kallithea-cli db-create -c my.ini --reuse
--reuseを指定しないと、DBやアカウントを作るところからやる。


my.ini内の情報はオプションでも指定できる。
===== ssh-addの自動登録 =====
kallithea-cli db-create -c my.ini --user=nn --password=secret --email=nn@example.com --repos=/srv/repos
ssh agentに秘密鍵の登録は以下のコマンド。
以下のエラー。
  ssh-add <秘密鍵のpath>
  ModuleNotFoundError: No module named 'MySQLdb'
ただし、上記コマンドは再起動すると登録が消えるので毎回必要。
mariadb_configをコピーするとか。共用サーバーだとこの問題の対応が難しいかもしれない。PostgreSQLでやり直す。


postgresqlを使うようにmy.iniを直して実行すると以下のエラー。
~/.ssh/configに以下の内容を記入しておくと、次回からkeychainから自動で読み込まれるらしい ([https://qiita.com/sonots/items/a6dec06f95fca4757d4a macOS で再起動しても ssh agent に秘密鍵を保持させ続ける二つの方法 #SSH - Qiita])。
  ModuleNotFoundError: No module named 'psycopg2'
  Host *
インストールしてみる。
  UseKeychain yes
pip install psycopg2
  AddKeysToAgent yes
動作した?以下の質問がきた。
うまくいかなかった。
Are you sure to destroy old database? [y/n]y


sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL:  password authentication failed for user "senooken_kallithea"
[https://aifan.jp/2022/01/25/ssh-add%E3%82%92pc%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E5%BA%A6%E3%81%AB%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E8%A8%AD%E5%AE%9A/ ssh-addをPC起動する度に自動的に実行させるための設定 | AIFAN]
p


パスワードを間違えた?yだと全削除になるからかな。nなら何も出なかった。
id_rsaの場合はIdentityFileを省略できるが、それ以外は指定が必要な模様。
Host *
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519


my.iniの指定がまずかった。
===== ssh経由でのリダイレクト出力 =====
#sqlalchemy.url = postgresql://kallithea:password@localhost/kallithea
[https://superuser.com/questions/400714/how-to-remotely-write-to-a-file-using-ssh bash - How to remotely write to a file using SSH - Super User]
sqlalchemy.url = postgresql://senooken_kallithea:WkiXF3w7d@localhost/senooken_kallithea
DBの指定も必要。


実行ログを見るといかが出ている。
ssh経由で標準入力内容からファイルをリダイレクトで作成したいことがある。
/virtual/senooken/public_html/kallithea/venv/lib64/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <<nowiki>http://initd.org/psycopg/docs/install.html#binary-install-from-pypi</nowiki>>.
  """)
インストールし直す。
pip install psycopg2-binary
実行し直し。
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "senooken_kallithea"
若干内容が変わる。ポート番号が怪しい。タイムオーバー。


https://chatgpt.com/c/67547095-c29c-800b-9530-650c7ff70756
sshのコマンド部分を文字列にすればOK。
ssh user@remotehost -T "cat > /remotefile.txt" <<-EOT
Some text
EOT
-Tで擬似端末を無効にしている。
===== パスフレーズの省略 =====
* [https://zenn.dev/luvmini511/articles/65786667221313 SSH パスフレーズ 省略したい!~ config 設定するか Keychain 登録自動化するか ~]
* [https://madoverload.com/2022/04/29/mac-ssh-agent/ Macのssh-agent]
SSH多段接続時とgit cloneでSSH鍵参照時に、パスフレーズを要求される。毎回要求されるのが手間。これを省略する方法がある。
~/.ssh/configに以下の設定を記述する。
Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519
* AddKeysToAgent=yesにすると、ssh-agentの実行時に自動的に鍵を追加する。
* UseKeychain=macOS専用。OSのキーチェーンからパスフレーズの検索を試みる。
* IdentityFile=SSH秘密鍵の絶対パス。デフォルトは~/.ssh/id_rsa。
上記3点で自動入力を試みる。
macOSで行う分には上記だけでパスワードは聞かれない。これをリモートでもやりたいなら、ssh-agentに登録が必要。
ログイン時に1回実行してくれたらいいので、ログインシェルの設定の~/.bash_profileに以下を記述。
echo 'ssh-add --apple-use-keychain' >>~/.bash_profile
これで端末の起動時に鍵を自動登録してくれるので、リモートでもパスフレーズを要求されない。


KallitheaはCGI未対応。見送ったほうがいいかも。
===== ssh_config =====
[https://linux.die.net/man/5/ssh_config ssh_config(5): OpenSSH SSH client config files - Linux man page]


=== Trac ===
重要な設定・構文がある。
https://chatgpt.com/c/67546eda-20ac-800b-b37f-7e8954c128f5


[https://trac.edgewall.org/ The Trac Project]
====== TOKENS ======
macのman ssh_configに詳しい。


CGIで動作するリポジトリー統合のあるBTS。
使用可能な指令が限定されている。


==== About ====
HostName (Macのみ)


===== 有名プロジェクト =====
* %h=リモートホスト名。Hostの指定部。
* %p=リモートポート。


* [https://trac.osgeo.org/ OSGeo Trac Instances]
====== WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! ======


==== Install ====
* [https://www.niandc.co.jp/tech/20150729_2464/ ssh接続をする際に「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」と出てつながらない|テクニカルブログ|日本情報通信株式会社]
[https://trac.edgewall.org/wiki/TracInstall TracInstall – The Trac Project]
* [https://qiita.com/hnw/items/0eeee62ce403b8d6a23c 「SSHホスト鍵が変わってるよ!」と怒られたときの対処 #SSH - Qiita]


[https://trac.edgewall.org/wiki/TracFastCgi TracFastCgi – The Trac Project]
ssh example.comなどを実行すると、IPアドレスの振り直しなどで、ホストの公開鍵が変わっていた場合、中間者攻撃への対策として失敗する。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!    @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:.
Please contact your system administrator.
Add correct host key in /Users/z.ken.senoo/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/z.ken.senoo/.ssh/known_hosts:1
Host key for [example.com]:3023 has changed and you have requested strict checking.
Host key verification failed.
Connection closed by UNKNOWN port 65535
Connection closed by UNKNOWN port 65535


[https://trac.edgewall.org/browser/tags/trac-1.6/INSTALL.rst tags/trac-1.6 の INSTALL.rst – The Trac Project]
$HOME/.ssh/known_hostsの該当行を削除すれば解決する。以下のコマンドでも対応してくれる。
ssh-keygen -R example.com


[https://zenn.dev/matobaa/articles/trac_16_on_docker Trac 1.6 を Docker で建てる]
==== curl ====
HTTPの通信のコマンドラインでの確認でよく使う。


[https://chatgpt.com/c/675504b7-29c0-800b-bb09-5e8a24709488 http s://chatgpt.com/c/675504b7-29c0-800b-bb09-5e8a24709488]
===== Basic =====
[https://curl.se/docs/tutorial.html curl - Tutorial]
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。


* [https://kiban.dbcls.jp/togordf/wiki/TracFastCgi TracFastCgi – TogoRDF]
<nowiki>*</nowiki>-F: multipart/formのform指定。
* [https://kiban.dbcls.jp/togordf/wiki/TracCgi TracCgi – TogoRDF]
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
* [https://qh73xebitbucketorg.readthedocs.io/ja/latest/1.Programmings/python/LIB/trac/install/ 1. 導入方法 — 苦労する遊び人の玩具箱 1 ドキュメント]
  <nowiki>http://www.example.com/postit.cgi</nowiki>
* [https://blog.masasuzu.net/entry/20101003/1285909461 virtualenv上でtrac-gitを動かして見る。 - 目の前に僕らの道がある]
@でfilename相当の指定。;でmime typeも指定できる。


「[https://trac.edgewall.org/browser/tags/trac-1.6/INSTALL.rst tags/trac-1.6 の INSTALL.rst – The Trac Project]」を参考に取り組む。
@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。


===== Installing Trac =====
===== curl: (60) SSL certificate problem: self-signed certificate =====
以下のディレクトリー構成を踏襲する。
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].
/var/www/kallithea/
├── config/                  # 設定ファイルやシークレットを保存
│  └── kallithea.ini        # Kallitheaのメイン設定ファイル
├── data/                    # データベースや一時ファイル用ディレクトリ
│  ├── db.sqlite            # SQLiteの場合のデータベースファイル
│  └── sessions/            # ユーザーセッションデータ
├── logs/                    # ログファイル保存ディレクトリ
│  └── kallithea.log        # メインのアプリケーションログ
├── repos/                  # Git/Mercurialリポジトリを保存するディレクトリ
│  ├── project1.git/       # プロジェクト1のGitリポジトリ
│  └── project2.hg/        # プロジェクト2のMercurialリポジトリ
├── static/                 # 静的ファイル(JavaScript, CSS, 画像など)
│  ├── css/
│  ├── js/
│  └── img/
└── venv/                    # Python仮想環境
    ├── bin/
    ├── lib/
    └── ...
複数のtrac環境がある場合、プロジェクト名部分がURLで分かれる模様。


インストーラーやOSのパッケージマネージャーを使う方法もある。公式の推奨はpipの模様。
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
pip3 install --user trac
レンタルサーバーのpip3を使うと以下のエラー。
PermissionError: [Errno 13] Permission denied: '/etc'
venvを挟む。
mkdir -p ~/public_html/trac
cd ~/public_html/trac
python3 -m venv --without-pip venv
. venv/bin/activate
curl <nowiki>https://bootstrap.pypa.io/pip/$(python3</nowiki> -V | grep -o '[0-9].[0-9]')/get-pip.py -o get-pip.py
python3 get-pip.py
pip install --upgrade pip
pipの環境ができたのでtracをインストールする。
pip3 install trac
trac-1.6をこれでインストールできた。


必要な依存関係をインストールする。
===== curl: Failed writing body =====
trac-admin [project] initenv
[https://askubuntu.com/questions/1449492/right-after-piping-to-head-tail-curl-23-failure-writing-output-to-desti pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu]
プロジェクトディレクトリーとプロジェクト名の命名に悩む。


Tracはプロジェクトという単位で管理する。1個のプロジェクトに関連するリポジトリーを複数まとめることは可能。fossil同様設定ファイルなどで手動で管理する。が、サードパーティープラグインでWeb UIから追加も可能とのこと。
以下のようにhead -n 1を指定するとcurlがエラーを出力する。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"        -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"        <nowiki>https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0</nowiki> | head -n 1


例えば、gnusocial/GNU socialというような形。
curl: Failed writing body
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。


[https://trac.edgewall.org/wiki/TracAdmin#initenv TracAdmin – The Trac Project]
対策は、curl -sで出力を抑制するとのこと。これで解決。
 
initenvは後ろにプロジェクト名とdbを指定できる。
trac-admin <project> initenv [<project name> <db>]
[project]/conf/trac.iniの以下に反映される。


* <project name>=project.name
==== Teleport ====
* <db>=trac.database (初期値=sqlite:db/trac.db)


https://chatgpt.com/c/67561e46-db8c-800b-80e8-b3f90bab4247
* [https://goteleport.com/docs/connect-your-client/teleport-connect/ Using Teleport Connect | Teleport Docs]
* [https://speakerdeck.com/gree_tech/greetechcon2023-session-a6 SSH から Teleport へ - Speaker Deck]


mysqlを使う場合、mysql:
踏み台サーバー (Jump server/Jump host) をよりよく管理するためのサーバーソフトウェア。


mysql:host=localhost;port=3306;dbname=your_database_name
アクセスログなどを一元管理できる。商用版とオープンソース版がある。


[https://trac.edgewall.org/wiki/TracEnvironment#DatabaseConnectionStrings TracEnvironment – The Trac Project]
基本的にteleportのサーバーを一度経由して、各種の踏み台サーバーにアクセスする。経由先が1個増えるが、そのおかげで監査ログを取得できたり、権限などを一括管理できる。


DB文字列の書式
ただ、teleportで監査ログを残すには、基本的にtshを経由する必要があり、既存のIDEなどのssh想定のソフトだと工夫が必要。tsh経由でやったり、rsyncで間にtshを挟むような工夫が必要。
mysql://username:password@host:port/dbname


===== tsh =====
teleportのコマンドラインクライアント。


[:]区切りの部分は順不同の模様。
tsh loginでteleportにログインする。
trac-admin gnusocial initenv 'GNU social' 'mysql://senooken_trac:password@localhost/senooken_trac';
localhostは省略不能。


[https://kiban.dbcls.jp/togordf/wiki/TracInstall TracInstall – TogoRDF]
環境変数
tracのmysql対応が不十分の模様。


PyMySQLモジュールを使う
[https://goteleport.com/docs/reference/cli/tsh/ tsh CLI reference | Teleport Docs]


[https://trac.edgewall.org/wiki/MySqlDb MySqlDb – The Trac Project]
* TELEPORT_PROXY: teleportプロキシーサーバーのアドレス。重要。
  pip install PyMySQL


===== ProxyJump+ProxyCommand =====
How To Use SSH ProxyJump and SSH ProxyCommand


コマンドを実行したらいかが表示される。
https://goteleport.com/blog/ssh-proxyjump-ssh-proxycommand/
Creating a new Trac environment at /virtual/senooken/public_html/trac/gnusocial
Project environment for 'GNU social' created.
You may configure the environment by editing the file:
  /virtual/senooken/public_html/trac/gnusocial/conf/trac.ini
You can run the Trac standalone web server `tracd` and point
your browser to <nowiki>http://localhost:8000/gnusocial</nowiki>.
  tracd --port 8000 /virtual/senooken/public_html/trac/gnusocial
Navigate to "Help/Guide" to browse the documentation for Trac,
including information on further setup (such as deploying Trac
to a real web server).
The latest documentation can also be found on the project
website:
  <nowiki>https://trac.edgewall.org/</nowiki>


~/.ssh/config のProxyJumpとProxyCommandの違いを整理する。


これでコマンドでローカルサーバーを起動できるようになっている。
どちらも中間サーバーを経由したリモートサーバーアクセスの指令。


===== Deploying Trac =====
* ProxyJump: 最も簡単な方法。OpenSSH v7,5以上で使用可能。中間サーバーでポート転送対応が前提条件。ProxyJumpは内部でProxyCommandを使う。
* ProxyCommand: ProxyJump搭乗前の方法。中間サーバーを介して標準入力と標準出力を転送して機能。


====== Runnning the Stadaalone Server ======
ProxyJumpの方が現代的だが、ProxyCommandの方が柔軟性が高い。
以下のコマンドでローカルサーバーで起動。
tracd --port 8000 </path/to/myproject>
このあと [http://localhost:8000<nowiki>] で開ける。tracdが把握する全環境を表示して、/myprojectで該当プロジェクトを開ける。なお、プロジェクトが1個の場合-sをつけると/myprojectのパスがトップディレクトリーになる模様。</nowiki>


===== Running Trac on a Web Server =====
ProxyJumpの使用例。
単独サーバーではなくWeb Server経由で実行することもできる。
{| class="wikitable"
|<code>ssh -J <jump server> <remote server>ssh -J <jump server1>,<jump server2>,<jump server3> <remote server></code>
|}
ProxyCommand
{| class="wikitable"
|<code>ssh -o ProxyCommand="ssh -W %h:%p <jump server>"</code> <code><remote server></code>
|}
~/.ssh/configの例。
{| class="wikitable"
|<code>Host remoteserver</code>


FastCGIでの動作なら共用サーバーでも稼働可能。
<code> HostName 192.168.200.200</code>


====== Generating the Trac cgi-bin directory ======
<code> User dev</code>
CGI用のスクリプトはtrac-admin deplyコマンドで生成する。
trac-admin /var/trac/<project> deploy var/www
ls /var/www


cgi-bin htdocs
<code> IdentityFile ~/.ssh/<your_key></code>


chmod ugo+x /var/www/cgi-bin/*
<code> Port 2048</code>
cgi-bin/は以下がある。
trac.cgi  trac.fcgi  trac.wsgi
実手順。
cd ~/public_html/trac
trac-admin gnusocial deploy .


ls
cgi-bin  get-pip.py  gnusocial  htdocs  venv
htdocsにはcommon siteがある。


trac-admin gnusocial deploy .でhtdocs配下にプロジェクトファイル群が共通で格納される模様。このhtdocsをdocument rootの公開ディレクトリにシンボリックリンクを作成するとよさそう。
<code> ## sample for</code> <code>ProxyJump</code>


====== Mapping Static Resources ======
<code> ProxyJump user@<jumpserver></code>  
tracの主な2個の静的リソースのURLパスが/chrome/commonと/chrome/site。追加で/chrome/<plugin>


deployコマンドは以下のディレクトリーを作成する。


* common/: tracの静的リソース。
<code> ## sample for</code> <code>ProxyCommand</code>
* site/: htdocsのコピー。
* shared: 複数のtracで共有する静的リソース。場所は[inherit].htdocs_dirで定義。
* <plugin>/


なお、静的リソースURLパスはtrac.iniで制御している
<code> ProxyCommand ssh -W %h:%p <jumpserver></code>
[trac]
|}
htdocs_location = <nowiki>http://static.example.org/trac-common/</nowiki>
ssh remoteserver で<jumpserver> 経由でremoteserverに接続できる。
上記設定に加えて以下のシンボリックリンク作成でchromeではなくtrac-commonを使える。
ln -s /path/to/trac/htdocs/common /var/www/static.example.org/trac-common
ここのパスがよくわからない。deployでtrac.gnusocial.jpを指定したほうがいいのかもしれない。


====== FastCGI ======
一般的に、ProxyJumpが推奨される感がある。ただ、teleportを導入している場合、ProxyJump/ProxyCommandを使うと、tshを経由していないのでteleportにログが残らないらしい。
[https://help.coreserver.jp/faq/ よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)]


CORESERVERでFastCGIの実行。
===== tsh経由ssh =====
ProxyJump/ProxyCommandを使わない場合、以下の形式でtshを使ってアクセスするのが基本。
tsh ssh 踏み台サーバーホスト名
tsh sshでteleportサーバーが管理している踏み台サーバーが見えるので、そこに接続できる。tshの後のsshは基本的に通常のsshと同じなので、sshの後にsshのコマンドを連鎖でき、対象サーバーにも一発でアクセスできる。
tsh ssh -At <jump host> ssh -A <target host>
-tでttyに繋いで標準入出力を接続。-Aはフォワーディング。ローカルのssh-addの情報などを連携できる。


/public_html/.fast-cgi-bin/ 内のphpXX.fcgiを編集。コントロールパネルのPHP設定でバージョンを指定。その後該当のphpXX.iniが対応公開ディレクトリーの処理スクリプトになる。
<jump host>の~/.ssh/configを用意しておくことで、<target host>にホスト名を指定したりできる。


trac.fcgiをphp81.fcgiに改名して、その後バージョンをコントロールパネルからphp81にする。これでOK。
ProxyJump/ProxyCommandと異なり、これだとちゃんとログを残せる。


シンボリックリンクのほうがいいか。
===== tsh経由scp =====
cd ~/public_html
cp php81.fcgi php81.fcgi.old
ln -fns ../trac/cgi-bin/trac.fcgi php81.fcgi
これだとダメ。


ChatGPTに記載のあった.htaccessをtrac.gnusocial.jpに配置したらそれで動作した。CORESERVERのFastCGIはPHPのみの模様。
* [https://goteleport.com/blog/teleport-files/ Teleport Files with SCP]
RewriteEngine On
* [https://goteleport.com/docs/connect-your-client/tsh/ Using the tsh Command Line Tool | Teleport Docs]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /cgi-bin/trac.cgi/$1 [L]
これでtrac.gnusocial.jpを開くと開けた。


ただし、基本のURLパスが [https://trac.gnusocial.jp/cgi-bin/trac.cgi/timeline<nowiki>] のようにcgiのパスがつくようになる。</nowiki>
tsh経由の踏み台サーバーへのファイル転送はやや工夫が必要。


なんか違う気がする。
tsh scpというコマンドが一応ある。が、これはネストなどには未対応。やる場合、以下のように2回実行になる。
FR=test.file TO=/path/to/test.file
tsh scp $FR <jump host>:$TO; tsh ssh -At <jump host> scp $TO <target host>:$TO
高ではなく、rsyncを使えば一発でいける。
rsync -e "tsh ssh -A <jump host> ssh" ./test.file <target host>:~/
これが基本。


元々の.fast-cgi-bin/php81.fcgiにtrac.fcgiのシンボリックリンクを配置した後。trac.gnusocial.jpにindex.phpを配置したら動作した?パスにindex.phpが入るようになったが。
====== PhpStorm ======
[https://goteleport.com/docs/enroll-resources/server-access/guides/jetbrains-sftp/ JetBrains SFTP | Teleport Docs]


https://chatgpt.com/c/6758c79e-f2e4-800b-88e2-7eab678f03f2
teleportの公式にマニュアルがあるが、記述が非常に不親切。これだと踏み台サーバーにしかアクセスできない。その先にアクセスできない。


CGIだとCGI用のパスが入るのはしかたない模様。
多段SSHの設定を残しておいて、ファイル転送だけrsyncで行う形になる。


https://chatgpt.com/c/6758c79e-f2e4-800b-88e2-7eab678f03f2
PhpStormのSSH configurationsのホスト名がスクリプトの引数に渡されるので、踏み台からAWSにsshでログインするホスト名やパソコンの~/.ssh/configのHostとの一致必要な点に注意する。
USERNAME=
IPV4=
VPCID=
cat <<-EOT >>~/.ssh/config
Host $VPCID
  ForwardAgent yes
  User $USERNAME
  ServerAliveInterval 30
  SendEnv -LC_* -LANG
  ProxyJump $USERNAME@teleport.security:3023
   
Host $USERNAME
    ForwardAgent yes
    ProxyJump $VPCID:22
    User $USERNAME
    Hostname $USERNAME.example.com
    ServerAliveInterval 30
    SendEnv -LC_* -LANG
   
Host $USERNAME.$VPCID
    # for automatic upload by PHPStorm
    LocalForward 22224 $USERNAME.$VPCID:22
    # for XDebug
    RemoteForward 9000 localhost:9000
    ForwardAgent yes
   
Host db-*
  HostName $IPV4
  LocalForward 3307 localhost:22
  ProxyCommand ssh $VPCID -W %h:%p
  ForwardAgent yes
   
Host *
    AddKeysToAgent yes
    PasswordAuthentication no
    User $USERNAME
    ForwardAgent yes
    ServerAliveInterval 30
    IdentityFile ~/.ssh/id_ed25519
    # for macOS
    UseKeychain yes
EOT
こんな感じの多段SSHの設定を用意。
踏み台サーバーにも同じホスト名でアクセスできるように、以下のような内容の~/.ssh/configをまだならば設定しておく。
{| class="wikitable"
|<code>AWS_HOSTNAME=</code>


リダイレクトして隠す。
<code>IPV4=</code>
RewriteEngine On
RewriteRule ^app$ /cgi-bin/script.cgi [L]
上記設定により、<code>example.com/app</code> というURLで <code>cgi-bin/script.cgi</code> が動作します。


===== Configuring Authentication =====
<code>VPCID=</code>


* [https://trac.edgewall.org/wiki/TracAuthenticationIntroduction TracAuthenticationIntroduction – The Trac Project]
<code>tsh ssh -A $VPCID "cat >>~/.ssh/config"</code> <code><<-EOT</code>
* [https://trac.edgewall.org/wiki/TracFastCgi TracFastCgi – The Trac Project]
* [https://trac.edgewall.org/wiki/TracModWSGI#ConfiguringAuthentication TracModWSGI – The Trac Project]


インストール後、管理者アカウントを作らないとログインできない。
<code>Host $AWS_HOSTNAME</code>


インストール方法別に、認証方法がある。
<code> HostName $IPV4</code>


基本的な考え
<code>EOT</code>
|}


* サイト全体の認証
* 一部の認証
** Basic認証
** Digest認証


コマンドで管理者アカウントを作ってやる感じだと思う。
rsync executable


===== SimpleMultiProject =====
rsyncで使用する (-eオプション)、以下の内容のシェルスクリプトを作成して実行権限を付与して任意の場所 (例: ~/project/tsh_ssh.sh) に配置する。
[https://trac.edgewall.org/wiki/TracMultipleProjects TracMultipleProjects – The Trac Project]
{| class="wikitable"
|<code>cd ~/project/</code>


https://chatgpt.com/c/675504b7-29c0-800b-bb09-5e8a24709488
<code>cat <<-'EOT'</code> <code>>tsh_ssh.sh</code>


[https://trac-hacks.org/wiki/SimpleMultiProjectPlugin SimpleMultiProjectPlugin – Trac Hacks - Plugins Macros etc.]
<code>tsh ssh -A <jump host> ssh $@</code>


Tracはもともと単一プロジェクトの管理用だが、外部プラグインで複数プロジェクトの管理も可能。
<code>EOT</code>


一番開発が盛んで安定していそうなのが、SimpleMultiProjectPlugin
<code>chmod +x tsh_ssh.sh</code>
|}




== Shell ==


=== Shell Command Language ===
PhpStorm設定


==== Compound Commands ====
PhpStormで以下を設定する。
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/V3_chap02.html#tag_18_09_04 Shell Command Language]


===== Case Conditional Construct =====
* [Tools]-[Deployment]-[Configuration]
case word in
* [+]-[SFTP]
    [(]pattern1) compound-list;;
* [Create New Server]-[New server name: 任意の名前 (例=rsync)]-[OK]
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
* [Connection] タブを以下に設定。
    [[(]pattern[ | pattern] ... ) compound-list]
*# Type=SFTP
esac
*# SSH configuration=以下を設定。
*## Host: <ホスト名> (例: ~/.ssh/configと踏み台サーバーの~/.ssh/configのホスト名と同じにする)
*## User name: ユーザー名
*## Port: 22
*## Authentication type: OpenSSH config and authentication agent
*# Root path=転送先のベース。
*# [☑️Use Rsync for download/upload/sync]
*# Rsync Settings=以下を設定。
*## Shell executable path=tsh_ssh.shのパス (例=~/project/tsh_ssh.sh)
* [Mappings] タブを以下に設定。
*# Local path: ローカルパソコンのディレクトリー
*# Deployment path: /
*# Web path: /
* [Settings]-[Build, Execution, Development]-[Development]-[Options]-[Upload changed files automatically to the default server]=[On explicit save action]
*# ☑️Delete remote files when local are deleted


* 未マッチで終了ステータス0。
以上で完了。後は同期したいファイルをPhpStormで開いて、右クリック-[Deployment]-[Upload to]/[Download from] でファイル転送できる。
* pattern部分: シェル展開が有効。他はglob。
* |でOR検索相当。
* 最後のパターンの;;は省略可能。if文のようにも使える。
* 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。


BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。
[☑️Use Rsync for download/upload/sync] のチェックを外せば、rsyncを使わないファイル転送になる。


=== ワイルドカード ===
=== Wireshark ===
ワイルドカードで.始まりのファイルをマッチさせたい。


以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
==== TLS ====
echo {.*,*}
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


=== BOM ===
Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
[https://stackoverflow.com/questions/3127436/adding-bom-to-utf-8-files unicode - Adding BOM to UTF-8 files - Stack Overflow]


ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
[Preferences]-[Protocols]-[TCP] を選ぶ。
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。


=== awk ===
* ☑Allow subdissector to reassemble TCP stream
[https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ The Open Group Base Specifications Issue 7]
* ☑Reassemble out-of-order semgemnts


==== 変数 ====
上記をチェックしておく。デフォルトでチェックされていた。


===== 特別 =====
続いて、セッションごとのPre-Master Secretを登録する。
* NF: 列数。列の全表示などで使う基本的で重要な変数。
* NR: 行番号。


===== スコープ =====
Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
[http://www.fukano.jp/study_of_awk/basic/basic08.htm 変数のスコープ]


関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


==== 文/statement ====
=== Security ===


* actions
==== DoS攻撃 ====
** if/else
いくつか対策方法がある。
** while/do...while/for
 
** break/continue
* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
** delete
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]
** next
 
** exit
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
* output
 
** print
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
** printf
 
==== バリデーションの実装 ====


==== 関数 ====
* [https://teratail.com/questions/81861 フロント側で入力チェックをしていればサーバー側では入力チェックは必要ない?]
* [https://qiita.com/mi2__user/items/f2f415ccbb0a625c8647 フロントエンドの"バリデーション"は最低限の方がいいらしい。 #TypeScript - Qiita]


===== 組込関数 =====
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。


* Arithmetic
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
** atan2
** cos
** sin
** exp
** log
** sqrt
** int
** rand
** srand
* String
** gsub
** index
** length
** match
** split
** sprintf
** sub
** substr
** tolower
** toupper
* I/O
** close
** getline
** system


print/printfは関数ではなく、statement/文扱い。
==== 二重送信 ====


==== ヘッダー出力、列別最大長さ出力。 ====
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 ()ユーフィット]
<nowiki>awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv</nowiki>
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]


==== CSV ====
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
[https://qiita.com/ko1nksm/items/19407c1c53cbbc50569a シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita]<syntaxhighlight lang="awk" line="1">
# csvparser.awk


## Usage
# ボタン連打
# awk -f csvparser.awk data.csv
# ブラウザーバック
# リロード (PRG)


# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
項目ごとにすべき対策が異なる。
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
 
function callback(row, len, fields,  col, field) {
===== 連打 =====
    for ( col = 1; col <= len; col++ ) {
 
        field = fields[col]
* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 ()ユーフィット]
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
* [https://codezine.jp/article/detail/769 JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)]
        print row ":" col " " field
* [https://blog.nisesagi.com/3150/ JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ]
    }
* [https://yutaihara.com/archives/569 Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com]
}
 
基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。


BEGIN { row = max_idx = 0 }
似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
{
$("form").submit(function() {
    idx = 0
  var self = this;
    sub(/\r$/, "")
  $(":submit", self).prop("disabled", true);
    while ($0 != "") {
  setTimeout(function() {
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
    $(":submit", self).prop("disabled", false);
            fields[++idx] = ""
  }, 10000);
        } else if (match($0, /^["]/)) {
});
            fields[++idx] = substr($0, 2)
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。
            for (;;) {
                if (getline == 0) exit 1
                sub(/\r$/, "")
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
                gsub(/["]["]/, "\"")
                fields[idx] = fields[idx] "\n" $0
            }
            fields[idx] = fields[idx] "\n"
        } else {
            exit 1
        }
        field = substr($0, RSTART, RLENGTH)
        $0 = substr($0, RSTART + RLENGTH)
        lastcomma = sub(/,$/, "", field) > 0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
        fields[idx] = fields[idx] field
    }
    if (lastcomma) fields[++idx] = ""
    while (idx < max_idx) delete fields[max_idx--]
    callback(++row, idx, fields)
    max_idx = idx
}


</syntaxhighlight>awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
=== Browser ===
tail -c +4 data/101543.csv | awk -f csvparser.awk


=== Other ===
==== Chromium ====


==== binary ====
===== Extension =====
[https://qiita.com/ko1nksm/items/dc8f247cdc5b7b58b736 POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita]
Chromme系で愛用拡張機能を列挙する。


バイナリーデータの読込はodコマンド。なければhexdump。
* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:


書込はprintf。
==== devtool/開発者ツール ====


head/tailの-cはPOSIXで使えたか?
===== イベントリスナー =====
[https://yuzu441.hateblo.jp/entry/2016/12/12/120000 要素に設定されているイベントを調べよう - ゆずめも]


==== root ====
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。


===== リダイレクト出力 =====
===== イベント監視 =====
[https://blog.shaba.dev/posts/redirect-with-sudo sudo権限でリダイレクト処理を行ってファイルに書き込む方法]
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]


リダイレクトはログインユーザーの権限でなされるらしく、root権限のある場所にファイル出力できない。
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。


teeコマンドでやる。
===== Network conditions =====
pwd | sudo tee out.dat
開発者ツールの[Network]タブを開いてリロードしても、[No internet]と表示されることがある。
teeコマンド実行する側でsudoが必要。


==== ログインシェルの確認 ====
これはオプション設定の問題。上のツールバーの[Disable cache]の右が[Offline] だとこうなる。これを[No throttling]にすると解決する。クリックミスだと思われる。
[https://docs.oracle.com/cd/E19683-01/816-3946/customize-89075/index.html 第 10 章 動作環境のカスタマイズ (Solaris ユーザ]


ログインシェルはGUIログインでも内部的にある。ログインシェルが読みこむprofileファイルなどは、ログイン時に、1回だけ実行したい処理の記述場所として最適。
==== Safari ====


SHELL環境変数にログインシェルのパスが入っている。
===== Windows Safari =====
echo $SHELL


/bin/bash
* [https://web.archive.org/web/20220220134447/https://jp.techcrunch.com/2012/07/27/20120725apple-safari-for-windows-ends/ Appleは静かにWindows版Safariの開発から手を引いてしまったのだろうか? | TechCrunch Japan]
* [http://web.archive.org/web/20120728130701/https://support.apple.com/kb/DL1531 Safari 5.1.7 for Windows]


==== OSの判別 ====
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
OSTYPE環境変数に値があるのでこれで判別する。


例えば以下の値が入っている。
===== 開発者ツール =====
linux-gnu
[https://www.e-bird.biz/blog/dev-ios/ PCでスマホサイトを見る方法 – Safari編|東京渋谷のWeb制作会社・ホームページ制作会社|株式会社イー・バード]
darwin23
これらを検知して判定する。
case $OSTYPE in
  linux*) echo 'linux';;
  darwin*) echo 'Mac';;
esac


== cmd.exe ==
Safariの開発者ツールは癖がある。


=== Control block ===
[設定]-[詳細]-[☑️Webデベロッパ用の機能を表示]


==== for ====
[開発]-[レスポンシブデザインモードにする]
あくまでコマンド。


===== nest =====
=== Other ===


* [https://chicagopile1-75.hatenablog.com/entry/2018/05/23/143502 バッチファイルで2重ループ - ハムスターに飼われる院生のブログ]
==== Tool ====


* [https://web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/ web.archive.org/web/20230602041631/https://jj-blues.com/cms/wantto-useloop/]
* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
* [https://tm-webtools.com/ TM - WebTools]


ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。


=== bitsadmin ===
==== localhost ====
Windowsでのファイルダウンロードコマンド


Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


書式:
RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。


=== certutil ===
IPv4=127.0.0.1/IPv6=::1とされている。
Windowsでのハッシュの確認に使える。
certutil -hashfile file


SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
== Shared Host ==
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。


=== rlogin.cmd ===
=== Free ===
コマンドキーの送信を自動化できる?
無料で使用可能な共用ホスティングサービスがある。
rem rlogin.cmd
@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=
Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%


=== 実行中プロセスのパスの確認 ===
==== スタードメイン無料サーバー ====
出典: [https://superuser.com/questions/768984/show-exe-file-path-of-running-processes-on-the-command-line-in-windows Show EXE file path of running processes on the command-line in Windows - Super User]。
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
wmic process get ProcessID,ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST


=== 簡易編集モード/挿入モード ===
[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]


* [https://softantenna.com/blog/windows-10-command-prompt-no-stop/ 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ]
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
* [https://superuser.com/questions/419717/windows-command-prompt-freezing-randomly Windows command prompt freezing randomly - Super User]


Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
* ディスク容量 20GB
* DB 1GB


cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。


そのほか、 <code>git log</code> のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
=== CORESERVER ===


[□挿入モード] にすると回避できる模様。
==== メール ====


== Web ==
* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


=== URL ===
情報


==== クエリー配列 ====
* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
* [https://bwt.blog.ss-blog.jp/2021-03-28 coreserverのメール設定:BWT Lab.:SSブログ]
* [https://qwerty.work/blog/2017/01/valueserver-spammail-filter-rule.php バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK]
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]


* [https://shinkufencer.hateblo.jp/entry/2019/05/18/163912 クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩]
ルールが特殊なので注意する。
* [https://qiita.com/s4kd0R/items/8a11d88099008bb1e9dc PHPでクエリパラメータから配列を受け取る物語 #JavaScript - Qiita]
* [https://www.php.net/http_build_query PHP: http_build_query - Manual]


やり方がいくつかある。
ゴミ箱に振り分ける場合。


# CSV文字列で受取後分割: <nowiki>https://www.sakdor.net/test/?var=1,2,3</nowiki> explode(",",$_GET[var]);
順1 で[<code>./.Trash</code>] を指定
# 配列添字
## http://www.sakdor.net/test/?var&#x5B;&#x5D;=1&var&#x5B;&#x5D;=2&var&#x5B;&#x5D;=3
## http://www.sakdor.net/test/?var&#x5B;a&#x5D;=1&var&#x5B;b&#x5D;=2&var&#x5B;c&#x5D;=3
## http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3


データが決まっているならcsvがシンプル。
順2


=== HTTP ===
* 条件:  [<code>.*</code>]
[https://www.rfc-editor.org/rfc/rfc9110.html RFC 9110: HTTP Semantics]
* 処理:  <code>./</code>、に振り分ける


==== Content-Disposition ====
条件部分には正規表現が使えるように見える。
[https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition Content-Disposition - HTTP | MDN]


[https://datatracker.ietf.org/doc/html/rfc6266 RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)]
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。


==== multipart/form-data ====
カスタムフィルターにくせがある。
rfc7578


* [https://datatracker.ietf.org/doc/html/rfc7578 RFC 7578 - Returning Values from Forms: multipart/form-data]
* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
* [https://qiita.com/sivertigo/items/14957200af5ad953d63b Multipart/form-dataの仕様メモ #HTTP - Qiita]


ファイルアップロード用のMIME type。
==== Value Domain ネットde診断 byGMO ====


リクエストヘッダー
* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
Content-Type: multipart/form-data; boundary=--hogehoge
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]
リクエストボディー
--hogehoge
Content-Disposition: form-data; name="user_name"
Content-Type: text/plain
test
--hogehoge
Content-Disposition: form-data; name="email"
sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"
male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg
\xff\xd8\....
--hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。


[https://weblabo.oscasierra.net/curl-post/ curlコマンドでPOSTする, 様々な形式別メモ |]
2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。


curlでの送信理由。
==== CGI ====


-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
* [https://senooken.jp/post/2020/02/21/3905/ CORESERVERでのFastCGI/CGI版PHPの利用手順 – senooken JP]
curl -X POST -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
* [https://help.coreserver.jp/faq/php-fast-cgi/ FastCGI版PHP 各バージョンのPHP設定方法 | よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)]
データとテキストを同時送信したい場合、-Fで複数指定する。
* [https://help.coreserver.jp/faq/php-cgi/ PHPをCGIとして動かす方法を教えてください | よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)]
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
* [https://engineer-milione.com/create/python-execution.html レンタルサーバー各社でのPythonの実行方法まとめ]
curlだと上記のboundaryなどをうまくやってくれるのだと思う。


リクエストボディー全体をファイルデータにする場合。
CORESERVERでのCGIの設定方法がある。
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg <nowiki>https://xxxxx.net/xxxxxx</nowiki>
{| class="wikitable"
|+CORESERVERのFastCGI版PHPとCGI版PHPの設定方法
!項目
!FastCGI
!CGI
|-
|バージョンの変更
|管理画面
|<code>.htaccess</code>内の
<code>AddHandler application/x-httpd-phpcgiXX .php</code>
|-
|設定ディレクトリー
| colspan="2" rowspan="1" |<code>/virtual/<username>/public_html/.fast-cgi-bin/</code>
|-
|CGIの実行ファイル
|<code>phpXX.fcgi</code>
|<code>phpXX.cgi</code>
|-
|PHPの設定ファイル
|<code>phpXX.ini</code>
|<code>php.ini</code>
|-
|設定の反映タイミング
|バージョン切替時
|即時
|}
~/public_html/.fast-cgi-bin/のphpXX.fcgi phpXX.cgiがCGIの実行ファイル。このファイルか最後の行のexecのパスを変更すると、自前コマンドに変更可能。


=== IP address ===
FastCGIは管理画面からバージョンを変更したタイミングで反映される。ただ、ファイル拡張子が.phpじゃないとこのFastCGIが実行されない模様。
出典: [https://glocalnet.jp/vpn/topix/archives/67#:~:text=%EF%BC%94%EF%BC%8E%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%20%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95%E3%81%AF%E4%B8%BB%E3%81%AB3%E3%81%A4%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82,%E3%83%BB%E5%A5%91%E7%B4%84%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%97%E3%83%AD%E3%83%90%E3%82%A4%E3%83%80%E3%81%A7%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E7%94%B3%E3%81%97%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95%20%E3%83%BB%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8BSIM%E3%82%92%E5%A5%91%E7%B4%84%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%20%E3%83%BBVPN%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E6%8F%90%E4%BE%9B%E4%BC%9A%E7%A4%BE%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット]。


自宅サーバーを行う際、固定IPアドレスが必要になる。
CGIは.htaccessに以下の内容を記述してCGI板PHPのバージョンを指定する。
AddHandler application/x-httpd-phpcgiXX .php
cgiのファイルには実行権限が必要。
chmod +x py.py
拡張子がないとダメな模様。加えて、.htaccessに以下の記述。
AddHandler cgi-script .py
これでpy.pyで動作はする。


取得方法がいくつかある。
拡張子じゃなくてファイル名で実行したい場合、SetHandlerでしていする ([https://senooken.jp/post/2019/06/01/2333/ AddType, AddHandler, SetHandlerの違い – senooken JP])。
<FilesMatch py$>
    SetHandler cgi-script
</FilesMatch>
これでpyでもアクセスできる。


* 契約しているプロバイダでオプションとして申し込む方法
FastCGI版の場合、以下のような設定でファイル名でマッチさせれば実行できそうな気もするが。
* 固定IPアドレスに対応しているSIMを契約する方法
<FilesMatch \.php$>
* '''VPNを利用した固定IPアドレスの提供会社を利用する方法'''
    SetHandler application/x-httpd-php
</FilesMatch>
500
<FilesMatch gnusocial$>
        SetHandler application/x-httpd-php
</FilesMatch>
pythonがphpとして認識され、テキストがそのまま表示される。


VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
SetHandler fcgid-scriptにしたらFastCGIで動作する。プログラムがFastCGI対応になっている必要がある。
<FilesMatch gnusocial$>
        SetHandler fcgid-script
</FilesMatch>


=== Authentication ===
== Analytics ==
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。


==== Basic認証 ====
==== Exam ====
出典: [https://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC Basic認証 - Wikipedia]。
<nowiki>##</nowiki> About


Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
<nowiki>https://gnusocial.jp/notice/4506679</nowiki>
GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA{{=}}{{=}}
盗聴や改ざんが簡単だが、シンプルという利点がある。


==== OAuth ====
<nowiki>###</nowiki> 全般
Ref


* [https://ja.wikipedia.org/wiki/OAuth OAuth - Wikipedia]
- マーケティング・ビジネス実務検定


OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
- IMA検定


以下が登場人物。
- Web検定


* resource owner: あるサイトのユーザー。
- ネットマーケティング検定
* resource server: あるサイトのユーザーのデータの保有サーバー。
* clent: クライアントアプリ。リソースサーバーのデータを使用したい。
* authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。


アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
<nowiki>###</nowiki> 解析系


処理の流れ。
- ウェブ解析士


# client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
- GAIQ
# client<-resource owner: Authorization Grant。
# client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
# client<-authorization server: Access Token
# client->resource server: Access Token。アクセストークンでアクセス。
# client<-resource server: Access Token


Consumer Key/Secret: アプリ識別用のID/PW。
- 統計検定


Access Token: サイトにアクセスするためのパスワード。
- Webアナリスト検定


=== API ===
GAIQが無料だしどうせ使うからいいかな。


==== 複数レコードの登録 ====
<nowiki>https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/</nowiki>
[https://buddypia.com/2021/11/14/%E8%A4%87%E6%95%B0%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89api%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F%E8%A9%B1/ 複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ]


既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
<nowiki>https://www.plan-b.co.jp/blog/seo/12792/</nowiki>


[https://www.yamarkz.com/blog/rest-web-api-practice REST WebAPIのプラクティス | yamarkz.com]
<nowiki>##</nowiki> URL
 
- <nowiki>https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/</nowiki>


delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
- <nowiki>https://mynavi-creator.jp/blog/article/qualification-for-web-marketer</nowiki>


==== パラメーター ====
- <nowiki>https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html</nowiki>
[https://stackoverflow.com/questions/25385559/rest-api-best-practices-args-in-query-string-vs-in-request-body json - REST API Best practices: args in query string vs in request body - Stack Overflow]


パラメーターの指定に3種類ある。
- <nowiki>https://digitor.jp/textbook/web-analytical-qualification/</nowiki>


# リクエストボディー
=== Tool ===
# クエリー
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。
# パス


パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
* SimilarWeb
* Ubersuggest
* ahrefs
* Googleキーワードプランナー


ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
=== 閲覧数取得 ===
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]。


この原則に従うとシンプルだろう。
* [行動]-[サイトコンテンツ]-[全てのページ]
* [表示する行数]=5000
* [エクスポート]=TSV


* URIには長さの制限がある。
=== 流入元特定 ===
* ボディー
「[https://support.google.com/analytics/thread/252885536/%E4%BC%9A%E5%93%A1%E7%99%BB%E9%8C%B2%E7%94%BB%E9%9D%A2%E3%81%AE%E6%B5%81%E5%85%A5%E5%85%83%E6%8E%A2%E7%B4%A2%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6?hl=ja 会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ]」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。<blockquote>こんにちは。
** 引数が非常に多い場合。
** 画像などバイナリーデータ。
** キー・値構造を持たない場合。
* クエリー文字列
** 引数を簡単に確認できる。
** 共通の引数の場合。


==== 検索機能のGET/POST ====
探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。


* [https://stackoverflow.com/questions/20550514/post-or-get-in-a-search-form .net - POST or GET in a search form? - Stack Overflow]
・自由形式レポートを作成


検索機能にGETとPOSTのどちらを使うか?という議論がある。
・セグメント作成 > ユーザーセグメント


データ登録するわけなじゃないのだから、GETがいいんじゃない?
・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定


POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存


GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
・探索レポートにセグメントを適用


ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。
・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列


==== レート制限対策 ====
・指標:セッション


* [https://pikodon.com/note/php/api-cache/ APIの利用制限対策 | Web開発ノート]
ご確認よろしくお願いいたします。
* [https://keirinomikata.zendesk.com/hc/ja/articles/4404549985945-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E6%95%B0%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E9%99%90%E3%81%AE%E5%AF%BE%E7%AD%96%E6%96%B9%E6%B3%95 リクエスト数によるアクセス制限の対策方法 – 請求管理ロボ ヘルプ]


いろいろ方法がある。
※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。


* cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。</blockquote>PMProでも似たような回答。<blockquote>Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session. </blockquote>
* 配列を利用して、1回のリクエストでまとめて取得する。
* インターバルを設ける。
* HTTP 429/413を検知して、リトライする。


==== 指数関数的バックオフ ====
== Server ==


* [https://docs.link.getmoneytree.com/docs/faq-rate-limiting APIレート制限は何か、どのように対処するのか?]
=== httpd ===
* [[wikipedia:Exponential_backoff|Exponential backoff - Wikipedia]]
Apache HTTP Server
* [https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja 指数バックオフ  |  Memorystore for Redis  |  Google Cloud]
* [https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/cloud-design-patterns/retry-backoff.html バックオフパターンで再試行 - AWS 規範ガイダンス]リトライ時は以下のアルゴリズムがいいらしい。
wait_interval = base * 2^n +/- jitter


* <code>wait_interval</code> は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
==== About ====
* <code>base</code> は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
httpdの利用可能な情報。
* <code>n</code> は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、<code>n</code>の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
* <code>jitter</code> は 0 から <code>base</code> の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し <code>wait_interval</code> の合計に加算するか減算するか、ランダムで選択してください。


==== バックエンドとフロントエンドの分離 ====
https://chatgpt.com/c/6761f851-df0c-800b-86e9-1624b458d66d
https://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45
# 使用可能な指令一覧
apachectl -L
httpd -L
# 使用可能なモジュール一覧
apachectl -M
httpd -M
.htaccessで使用可能な指令の一覧。


SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。
[https://senooken.jp/post/2019/04/19/2010/ .htaccessで使用可能な指令一覧 – senooken JP]


SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。
==== Operation ====
サーバーの稼働や状態確認などで重要な操作がいくつかある。systemd前提。


SSRの利点。
ログ・状態確認。
sudo systemctl status apache2
sudoをつけないと詳細ログを確認できない。
sudo systemctl restart apache2
sudo systemctl start apache2
sudo systemctl stop apache2


* SEO
==== Access Control ====
* 初期表示。
* 匿名。


SSRの課題。
* [https://httpd.apache.org/docs/2.4/en/howto/access.html Access Control - Apache HTTP Server Version 2.4]
* [https://httpd.apache.org/docs/2.4/en/howto/auth.html Authentication and Authorization - Apache HTTP Server Version 2.4]
* [https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_core.html#logic mod_authz_core - Apache HTTP Server Version 2.4]


* サーバー負荷: データとHTML作成を同時に行うから。
DoS攻撃対策などで重要な設定。
* 分散困難:


キャッシュの活用がポイントになるとのこと。
mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。


=== Network ===
基本構文は以下。
Require host <address>
Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。


==== ssh ====
Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。


===== ssh-addの自動登録 =====
==== mod_cgi ====
ssh agentに秘密鍵の登録は以下のコマンド。
[https://httpd.apache.org/docs/current/en/mod/mod_cgi.html mod_cgi - Apache HTTP Server Version 2.4]
ssh-add <秘密鍵のpath>
ただし、上記コマンドは再起動すると登録が消えるので毎回必要。


~/.ssh/configに以下の内容を記入しておくと、次回からkeychainから自動で読み込まれるらしい ([https://qiita.com/sonots/items/a6dec06f95fca4757d4a macOS で再起動しても ssh agent に秘密鍵を保持させ続ける二つの方法 #SSH - Qiita])。
CGIプロトコルのApacheモジュール。cgi-scriptにハンドラーを割り当てるとCGIとして扱う。
Host *
  UseKeychain yes
  AddKeysToAgent yes
うまくいかなかった。


[https://aifan.jp/2022/01/25/ssh-add%E3%82%92pc%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E5%BA%A6%E3%81%AB%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E8%A8%AD%E5%AE%9A/ ssh-addをPC起動する度に自動的に実行させるための設定 | AIFAN]
==== mod_fcgid ====
[https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html mod_fcgid - Apache HTTP Server Version 2.5]


id_rsaの場合はIdentityFileを省略できるが、それ以外は指定が必要な模様。
FastCGIプロトコルのApacheモジュール。AddHandlerかSetHandlerでfcgid-scriptハンドラーに割り当てられると、FastCGIとして処理される。
Host *
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519


===== ssh経由でのリダイレクト出力 =====
プログラム側もFastCGIに対応している必要がある。
[https://superuser.com/questions/400714/how-to-remotely-write-to-a-file-using-ssh bash - How to remotely write to a file using SSH - Super User]


ssh経由で標準入力内容からファイルをリダイレクトで作成したいことがある。
==== Error ====
sudo systemctl status apache2


sshのコマンド部分を文字列にすればOK。
● apache2.service - The Apache HTTP Server
ssh user@remotehost -T "cat > /remotefile.txt" <<-EOT
      Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Some text
    Drop-In: /etc/systemd/system/apache2.service.d
  EOT
              └─privatetmp.conf
-Tで擬似端末を無効にしている。
      Active: failed (Result: exit-code) since Fri 2024-12-06 15:09:28 JST; 12s ago
        Docs: <nowiki>https://httpd.apache.org/docs/2.4/</nowiki>
    Process: 38461 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: [Fri Dec 06 15:09:28.259153 2024] [core:warn] [pid 38464] AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00112: Warning: DocumentRoot [/home/gree/frontend/greenet/htdocs_net] does not exist
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00526: Syntax error on line 7 of /etc/apache2/conf-available/rewrite-greenet.conf:
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: RewriteRule: unknown flag 'UnsafeAllow3F'
  Dec 06 15:09:28 z-ken-senoo apachectl[38461]: Action 'start' failed.
  Dec 06 15:09:28 z-ken-senoo apachectl[38461]: The Apache error log may have more information.
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Control process exited, code=exited, status=1/FAILURE
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Failed with result 'exit-code'.
Dec 06 15:09:28 z-ken-senoo systemd[1]: Failed to start The Apache HTTP Server.


==== curl ====
===== AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8 =====
HTTPの通信のコマンドラインでの確認でよく使う。
NameVirtualHost指令が廃止予定なので、行を削除して対応する。


===== Basic =====
===== AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf. =====
[https://curl.se/docs/tutorial.html curl - Tutorial]
* -X: メソッド指定
* -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。


<nowiki>*</nowiki>-F: multipart/formのform指定。
* Gentooの~amd64にApache 2.4.1が来たので試してみた https://meihong.work/computer/server-administration/apache/gentoo%E3%81%AEamd64%E3%81%ABapache-2-4-1%E3%81%8C%E6%9D%A5%E3%81%9F%E3%81%AE%E3%81%A7%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
* Upgrading to 2.4 from 2.2 https://httpd.apache.org/docs/2.4/upgrading.html
  <nowiki>http://www.example.com/postit.cgi</nowiki>
* DefaultType Directive https://httpd.apache.org/docs/2.4/en/mod/core.html#defaulttype
@でfilename相当の指定。;でmime typeも指定できる。


@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。
DefaultTypeはnone以外意味がなく、警告表示になる模様。


===== curl: (60) SSL certificate problem: self-signed certificate =====
==== .htaccess ====
Ref: [https://linuxfan.info/curl-insecure curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI].


--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
===== directive =====
[https://senooken.jp/post/2019/04/19/2010/ .htaccessで使用可能な指令一覧 – senooken JP]


===== curl: Failed writing body =====
.htaccessで使用不能なよく登場して誤解する指令を整理しておく。
[https://askubuntu.com/questions/1449492/right-after-piping-to-head-tail-curl-23-failure-writing-output-to-desti pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu]


以下のようにhead -n 1を指定するとcurlがエラーを出力する。
* Alias
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"        -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"        <nowiki>https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0</nowiki> | head -n 1
* ScriptAlias
* Directory/DirectoryMatch
* Location/LocationMatch
逆にOKなもの。


curl: Failed writing body
* Files/FilesMatch
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。


対策は、curl -sで出力を抑制するとのこと。これで解決。
=== E-mail ===
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]


=== Wireshark ===
MailHog: Go言語製のメールサーバーソフト。


==== TLS ====
=== Debian ===
Ref: [https://www.toyo.co.jp/onetech_blog/articles/detail/id=36994 SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー].


Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
==== PHP8 ====
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](<nowiki>https://computingforgeeks.com/how-to-install-php-on-debian-linux/</nowiki>)


[Preferences]-[Protocols]-[TCP] を選ぶ。
Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。


* ☑Allow subdissector to reassemble TCP stream
sudo apt update
* ☑Reassemble out-of-order semgemnts


上記をチェックしておく。デフォルトでチェックされていた。
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2


続いて、セッションごとのPre-Master Secretを登録する。
PHPパッケージを追加する。


Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
echo "deb <nowiki>https://packages.sury.org/php/</nowiki> $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list


以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
wget -qO - <nowiki>https://packages.sury.org/php/apt.gpg</nowiki> | sudo apt-key add -
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。


=== Security ===
sudo apt update


==== DoS攻撃 ====
これでPHP8を参照できるので、インストールする。
いくつか対策方法がある。


* [https://lite.ip2location.com/ip-address-ranges-by-country?lang=ja 国別のIPアドレス範囲]
sudo apt install php8.2
* [https://rakko.tools/tools/11/ IPアドレスから住所検索:国、地域の特定 | ラッコツールズ🔧]


サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](<nowiki>https://tecadmin.net/switch-between-multiple-php-version-on-debian/</nowiki>)


攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
インストールしたら、PHPのバージョンを切り替える。


==== バリデーションの実装 ====
a2dismod php7.4


* [https://teratail.com/questions/81861 フロント側で入力チェックをしていればサーバー側では入力チェックは必要ない?]
a2enmod php8.2
* [https://qiita.com/mi2__user/items/f2f415ccbb0a625c8647 フロントエンドの"バリデーション"は最低限の方がいいらしい。 #TypeScript - Qiita]


基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
sudo systemctl restart apache2


ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
php 8.2にするとこういうエラー。


==== 二重送信 ====
[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104


* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]


submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。


# ボタン連打
私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
# ブラウザーバック
# リロード (PRG)


項目ごとにすべき対策が異なる。
==== alternative ====
Ref: [https://wiki.debian.org/DebianAlternatives DebianAlternatives - Debian Wiki].


===== 連打 =====
OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。<syntaxhighlight lang="sh">
sudo update-alternatives --display vi
sudo update-alternatives --config vi
</syntaxhighlight>オプションとコマンド名を指定することで、現在の実体と更新ができる。


* [https://www.youfit.co.jp/archives/4545 フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット]
=== XAMPP ===
* [https://qiita.com/syobochim/items/120109315f671918f28d さいきょうの二重サブミット対策 #JavaScript - Qiita]
* [https://codezine.jp/article/detail/769 JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)]
* [https://blog.nisesagi.com/3150/ JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ]
* [https://yutaihara.com/archives/569 Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com]


基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。
==== ポート番号変更 ====
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]


似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
XAMPP Control PanelのConfigから変更可能。
$("form").submit(function() {
  var self = this;
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。


=== Browser ===
phpmyadminはConfigのphpmyadminで、Servers.portを追加する。


==== Chromium ====
== Vim ==


===== Extension =====
=== Other ===
Chromme系で愛用拡張機能を列挙する。


* [https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm Create Link]:
==== Async ====
https:/github.com/skywind3000/asyncrun.vim


==== devtool/開発者ツール ====
asyncrun.vimは1個のバックグラウンド処理しか対応していない。


===== イベントリスナー =====
<nowiki>https://github.com/skywind3000/asyncrun.vim/issues/12</nowiki>
[https://yuzu441.hateblo.jp/entry/2016/12/12/120000 要素に設定されているイベントを調べよう - ゆずめも]


[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
vim-dispatchならいけるのか?


===== イベント監視 =====
==== Binary ====
[https://stackoverflow.com/questions/3787555/how-to-find-out-which-javascript-events-fired How to find out which JavaScript events fired? - Stack Overflow]
[https://vim-jp.org/vim-users-jp/2010/03/21/Hack-133.html vim-jp » Hack #133: バイナリファイルを編集する]


monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。
==== grep ====
非同期でgrepする方法。


==== Other ====
<nowiki>https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously</nowiki>


===== Windows Safari =====
<nowiki>https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/</nowiki>


* [https://web.archive.org/web/20220220134447/https://jp.techcrunch.com/2012/07/27/20120725apple-safari-for-windows-ends/ Appleは静かにWindows版Safariの開発から手を引いてしまったのだろうか? | TechCrunch Japan]
Vim 8の非同期APIはプラグイン用。
* [http://web.archive.org/web/20120728130701/https://support.apple.com/kb/DL1531 Safari 5.1.7 for Windows]


一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
<nowiki>*</nowiki> <nowiki>https://github.com/mhinz/vim-grepper</nowiki>


=== Other ===
<nowiki>*</nowiki> <nowiki>https://github.com/skywind3000/asyncrun.vim</nowiki>


==== Tool ====
<nowiki>*</nowiki> <nowiki>https://github.com/tpope/vim-dispatch</nowiki>


* [https://web-toolbox.dev/ Web ToolBox | 開発者向けのオンラインツール]
<nowiki>https://wonderwall.hatenablog.com/entry/2017/10/09/210000</nowiki>
* [https://tm-webtools.com/ TM - WebTools]


いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
asyncrun.vimでやるのがよさそう。


==== localhost ====
==== AnsiEsc ====
<nowiki>*</nowiki> https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors


* [[wikipedia:Special-use_domain_name|Special-use domain name - Wikipedia]]
<nowiki>*</nowiki> https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly
* [https://ja.wikipedia.org/wiki/.localhost .localhost - Wikipedia]


RFC 6761 で規定。RFC 2606<nowiki/>で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
本家は太字に対応していないのでこちらがいいかな。


IPv4=127.0.0.1/IPv6=::1とされている。
- https:/github.com/powerman/vim-plugin-AnsiEsc


== Shared Host ==
ただし、こちらはgvimでクリック時にカーソル位置がずれる。
 
=== program ===


=== Free ===
==== C ====
無料で使用可能な共用ホスティングサービスがある。
[https://daisuzu.hatenablog.com/entry/2012/05/06/204019 ワシのVimプラグインは百八式まであるぞ - daisuzu's notes]


==== スタードメイン無料サーバー ====
【C/C++】
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。


[https://www.star-domain.jp/service/free_server.php 無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~]
     87. a.vim


jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
        C/C++のヘッダとソースを切り替えます。


* ディスク容量 20GB
     88. c.vim
* DB 1GB


ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
        C/C++のテンプレートやイディオムの入力をサポートしてくれます。


=== CORESERVER ===
     89. CCTree


==== メール ====
        cscopeを使って関数のコールグラフを表示してくれます。


* [https://www2.bwt.jp/wiki/?Custom_Filter_of_Coreserver Custom_Filter_of_Coreserver - PukiWiki]
     90. Source-Explorer-srcexpl.vim
* [https://help.coreserver.jp/manual/v2/spam-filter/ スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]
* [https://help.coreserver.jp/manual/v1/customfilter/ カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)]


情報
        ソース解析ツール、Source InsightのVim版です。


* [https://www2.bwt.jp/wiki/?CoreServer_Mail_Custom CoreServer_Mail_Custom - PukiWiki]
     91. trinity.vim
* [https://bwt.blog.ss-blog.jp/2021-03-28 coreserverのメール設定:BWT Lab.:SSブログ]
* [https://qwerty.work/blog/2017/01/valueserver-spammail-filter-rule.php バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK]
* [https://awmt.jp/dekirukana/archives/2253 コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?]


ルールが特殊なので注意する。
        taglist, srcexpl, nerdtreeを同時に起動して


ゴミ箱に振り分ける場合。
        VimがIDE画面のような画面になります。


順1 で[<code>./.Trash</code>] を指定
     92. cscope-menu


順2
        cscope用のメニューを表示してくれます。


* 条件:  [<code>.*</code>]
     93. gtags.vim
* 処理:  <code>./</code>、に振り分ける


条件部分には正規表現が使えるように見える。
        gtagsを使ってファイルを開けます。


破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
     94. DoxygenToolkit.vim


カスタムフィルターにくせがある。
        Doxygenコメントの入力をサポートしてくれます。


* エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
== Visual Studio Code ==


==== Value Domain ネットde診断 byGMO ====
=== Keybind ===


* [https://www.value-domain.com/information/detail/?no=20240606-1 弊社レンタルサーバー上で運用中のドメインにおける自動セキュリティ診断開始のお知らせ | お知らせ - バリュードメイン]
==== 矩形選択 ====
* [https://www.value-domain.com/security/net-de-shindan/ Value Domain ネットde診断 byGMO - バリュードメイン]
Ref: [https://mitomito.hatenablog.jp/entry/2021/01/27/073000#:~:text=VS%20Code%E3%81%AE%E7%9F%A9%E5%BD%A2%E9%81%B8%E6%8A%9E%E3%81%A8%E7%9F%A9%E5%BD%A2%E8%B2%BC%E4%BB%98%E3%81%AE%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95%201%20%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%A7%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%20shift%20%2B%20alt%20%2B,shift%20%2B%20alt%20%2B%20%E7%9F%A2%E5%8D%B0%E3%81%A7%E4%BB%BB%E6%84%8F%E3%81%AE%E7%AF%84%E5%9B%B2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%80%81%20%28or%20%E5%88%87%E3%82%8A%E5%8F%96%E3%82%8A%29%E3%81%99%E3%82%8B%20 VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog].


2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
* s-alt-クリック
* c-s-alt-矢印
ジャンプ


== Analytics ==
* 括弧ジャンプ: C-S-\


==== Exam ====
=== Config ===
<nowiki>##</nowiki> About


<nowiki>https://gnusocial.jp/notice/4506679</nowiki>
==== Default terminal ====
Ref: [https://stackoverflow.com/questions/44435697/change-the-default-terminal-in-visual-studio-code bash - Change the default terminal in Visual Studio Code - Stack Overflow].


<nowiki>###</nowiki> 全般
[F1]-[Terminal: Select Default Profile]


- マーケティング・ビジネス実務検定
=== cscope ===
cscope用のプラグインが何個かある。


- IMA検定
* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]


- Web検定
scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。


- ネットマーケティング検定
cscope-codeはシンプルだが動作した。こちらを当分使うことにする。


<nowiki>###</nowiki> 解析系
Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。


- ウェブ解析士
=== Vim ===


- GAIQ
* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]


- 統計検定
VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。


- Webアナリスト検定
=== Extension ===
CSS


GAIQが無料だしどうせ使うからいいかな。
Tailwind CSS IntelliSense


<nowiki>https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/</nowiki>
==== PHP ====
Laravel Blade Snippets


<nowiki>https://www.plan-b.co.jp/blog/seo/12792/</nowiki>
===== PHP Intelephense =====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].


<nowiki>##</nowiki> URL
VSCodeのPHPの補完拡張として人気が高い。


- <nowiki>https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/</nowiki>
====== Quick Start ======
設置後、しておくべき設定がある。


- <nowiki>https://mynavi-creator.jp/blog/article/qualification-for-web-marketer</nowiki>
* Go to <code>Extensions</code>.
* Search for <code>@builtin php</code>
* Disable <code>PHP Language Features</code>. Leave <code>PHP Language Basics</code> enabled for syntax highlighting.


- <nowiki>https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html</nowiki>
VSCodeの [PHP Language Features] を無効にしておくとのこと。


- <nowiki>https://digitor.jp/textbook/web-analytical-qualification/</nowiki>
後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。


=== Tool ===
====== Module ======
サイト分析用のツールがいくつかある ([https://hidesunblog.com/blog-ranking-sites/ 2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】])。
peclなどPHPの標準モジュールで一部認識できないものがある。


* SimilarWeb
「[https://stackoverflow.com/questions/62258598/undefined-type-imagick-in-vscodes-intelephense php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow]」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
* Ubersuggest
* ahrefs
* Googleキーワードプランナー


=== 閲覧数取得 ===
====== Coding ======
出典: [https://affiliate-jpn.com/archives/5595 GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN]
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].


* [行動]-[サイトコンテンツ]-[全てのページ]
intelephenseでコード補完を認識しやすい書き方というのがある。
* [表示する行数]=5000
* [エクスポート]=TSV


=== 流入元特定 ===
まず、型をつけられるものはつける。<syntaxhighlight lang="php">
「[https://support.google.com/analytics/thread/252885536/%E4%BC%9A%E5%93%A1%E7%99%BB%E9%8C%B2%E7%94%BB%E9%9D%A2%E3%81%AE%E6%B5%81%E5%85%A5%E5%85%83%E6%8E%A2%E7%B4%A2%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6?hl=ja 会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ]」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。<blockquote>こんにちは。
function superMethod()
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。


探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
=== Other ===


・自由形式レポートを作成
==== Remote ====
[https://www.mathkuro.com/vs-code/upload-and-download-remote-file/ 【WinSCPはもう不要?】VS Codeのダウンロード/アップロード機能が便利すぎる!! | マスクロドットコム]


・セグメント作成 > ユーザーセグメント
[https://code.visualstudio.com/docs/remote/remote-overview Visual Studio Code Remote Development]


・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
公式拡張機能のVS Code Remote Developmentを使うと、リモートファイルをVS Codeで開いて、ドラッグドロップでファイル送受信ができるらしい。


・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
== PhpStorm ==


・探索レポートにセグメントを適用
=== Encoding ===


・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
* [https://pleiades.io/help/phpstorm/encoding.html エンコード | PhpStorm ドキュメント]
* [https://pleiades.io/help/phpstorm/settings-file-encodings.html ファイルエンコーディング | PhpStorm ドキュメント]


・指標:セッション
パス単位で文字エンコーディングを設定可能。


ご確認よろしくお願いいたします。
[PhpStorm]-[Settings]-[Editor]-[File Encodings] から行う。


※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
=== Scratch ===
[https://qiita.com/endam/items/cc2c4c2aee8d382acd9e 【New Year Calendar】君はPhpStormのScratch機能を知っているか #NewYearCalendar - Qiita]


 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。</blockquote>PMProでも似たような回答。<blockquote>Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session. </blockquote>
メモなどの一時ファイルの作成機能。


== Server ==
[File]-[New Scratch File] からファイル形式を選んで作る。困ったらMarkdownで良いだろう。


=== httpd ===
作成したScratchファイルは [Project]-[Scratches and Consoles]-[Scratches] に格納される。
Apache HTTP Server


==== Operation ====
=== 矩形選択 ===
サーバーの稼働や状態確認などで重要な操作がいくつかある。systemd前提。
[https://pleiades.io/help/phpstorm/multicursor.html#find-and-select-multiple-occurrences-of-a-string 複数のカーソルと選択範囲 | PhpStorm ドキュメント]


ログ・状態確認。
方法がいくつかある。
sudo systemctl status apache2
sudoをつけないと詳細ログを確認できない。
sudo systemctl restart apache2
sudo systemctl start apache2
sudo systemctl stop apache2


==== Access Control ====
* Cmd-Shift-8
* Option-Shift-Middle


* [https://httpd.apache.org/docs/2.4/en/howto/access.html Access Control - Apache HTTP Server Version 2.4]
== PIM ==
* [https://httpd.apache.org/docs/2.4/en/howto/auth.html Authentication and Authorization - Apache HTTP Server Version 2.4]
[https://ja.wikipedia.org/wiki/Personal_Information_Manager Personal Information Manager - Wikipedia]
* [https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_core.html#logic mod_authz_core - Apache HTTP Server Version 2.4]


DoS攻撃対策などで重要な設定。
PIMという個人情報管理用アプリの分類がある。


mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
* カレンダー
* アドレス帳
* 電子メール
* タスク管理
* メモ帳
* 音声メモ
* 電卓
* 時計
* 電子辞書


基本構文は以下。
=== E-mail ===
Require host <address>
Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。


Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
==== General ====
 
==== Error ====
sudo systemctl status apache2
 
● apache2.service - The Apache HTTP Server
      Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/apache2.service.d
              └─privatetmp.conf
      Active: failed (Result: exit-code) since Fri 2024-12-06 15:09:28 JST; 12s ago
        Docs: <nowiki>https://httpd.apache.org/docs/2.4/</nowiki>
    Process: 38461 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: [Fri Dec 06 15:09:28.259153 2024] [core:warn] [pid 38464] AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00112: Warning: DocumentRoot [/home/gree/frontend/greenet/htdocs_net] does not exist
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00526: Syntax error on line 7 of /etc/apache2/conf-available/rewrite-greenet.conf:
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: RewriteRule: unknown flag 'UnsafeAllow3F'
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: Action 'start' failed.
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: The Apache error log may have more information.
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Control process exited, code=exited, status=1/FAILURE
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Failed with result 'exit-code'.
Dec 06 15:09:28 z-ken-senoo systemd[1]: Failed to start The Apache HTTP Server.
 
===== AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8 =====
NameVirtualHost指令が廃止予定なので、行を削除して対応する。
 
===== AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf. =====
 
* Gentooの~amd64にApache 2.4.1が来たので試してみた https://meihong.work/computer/server-administration/apache/gentoo%E3%81%AEamd64%E3%81%ABapache-2-4-1%E3%81%8C%E6%9D%A5%E3%81%9F%E3%81%AE%E3%81%A7%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
* Upgrading to 2.4 from 2.2 https://httpd.apache.org/docs/2.4/upgrading.html
* DefaultType Directive https://httpd.apache.org/docs/2.4/en/mod/core.html#defaulttype
 
DefaultTypeはnone以外意味がなく、警告表示になる模様。
 
=== E-mail ===
[[https://www.itti.jp/web-direction/spam-blacklist-release/ サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]]
 
MailHog: Go言語製のメールサーバーソフト。
 
=== Debian ===
 
==== PHP8 ====
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](<nowiki>https://computingforgeeks.com/how-to-install-php-on-debian-linux/</nowiki>)
 
Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
 
sudo apt update
 
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
 
PHPパッケージを追加する。
 
echo "deb <nowiki>https://packages.sury.org/php/</nowiki> $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
 
wget -qO - <nowiki>https://packages.sury.org/php/apt.gpg</nowiki> | sudo apt-key add -
 
sudo apt update
 
これでPHP8を参照できるので、インストールする。
 
sudo apt install php8.2
 
[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](<nowiki>https://tecadmin.net/switch-between-multiple-php-version-on-debian/</nowiki>)
 
インストールしたら、PHPのバージョンを切り替える。
 
a2dismod php7.4
 
a2enmod php8.2
 
sudo systemctl restart apache2
 
php 8.2にするとこういうエラー。
 
[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104
 
念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
 
<<nowiki>https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development</nowiki>> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
 
私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
 
==== alternative ====
Ref: [https://wiki.debian.org/DebianAlternatives DebianAlternatives - Debian Wiki].
 
OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。<syntaxhighlight lang="sh">
sudo update-alternatives --display vi
sudo update-alternatives --config vi
</syntaxhighlight>オプションとコマンド名を指定することで、現在の実体と更新ができる。
 
=== XAMPP ===
 
==== ポート番号変更 ====
[https://qiita.com/neneta0921/items/3c2f9ac8ea9b5bcfc6e6 Xamppでポート競合を防ぐ方法 #PHP - Qiita]
 
XAMPP Control PanelのConfigから変更可能。
 
phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
 
== Vim ==
 
=== Other ===
 
==== Async ====
https:/github.com/skywind3000/asyncrun.vim
 
asyncrun.vimは1個のバックグラウンド処理しか対応していない。
 
<nowiki>https://github.com/skywind3000/asyncrun.vim/issues/12</nowiki>
 
vim-dispatchならいけるのか?
 
==== Binary ====
[https://vim-jp.org/vim-users-jp/2010/03/21/Hack-133.html vim-jp » Hack #133: バイナリファイルを編集する]
 
==== grep ====
非同期でgrepする方法。
 
<nowiki>https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously</nowiki>
 
<nowiki>https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/</nowiki>
 
Vim 8の非同期APIはプラグイン用。
 
<nowiki>*</nowiki> <nowiki>https://github.com/mhinz/vim-grepper</nowiki>
 
<nowiki>*</nowiki> <nowiki>https://github.com/skywind3000/asyncrun.vim</nowiki>
 
<nowiki>*</nowiki> <nowiki>https://github.com/tpope/vim-dispatch</nowiki>
 
<nowiki>https://wonderwall.hatenablog.com/entry/2017/10/09/210000</nowiki>
 
asyncrun.vimでやるのがよさそう。
 
==== AnsiEsc ====
<nowiki>*</nowiki> https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors
 
<nowiki>*</nowiki> https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly
 
本家は太字に対応していないのでこちらがいいかな。
 
- https:/github.com/powerman/vim-plugin-AnsiEsc
 
ただし、こちらはgvimでクリック時にカーソル位置がずれる。
 
=== program ===
 
==== C ====
[https://daisuzu.hatenablog.com/entry/2012/05/06/204019 ワシのVimプラグインは百八式まであるぞ - daisuzu's notes]
 
【C/C++】
 
     87. a.vim
 
        C/C++のヘッダとソースを切り替えます。
 
     88. c.vim
 
        C/C++のテンプレートやイディオムの入力をサポートしてくれます。
 
     89. CCTree
 
        cscopeを使って関数のコールグラフを表示してくれます。
 
     90. Source-Explorer-srcexpl.vim
 
        ソース解析ツール、Source InsightのVim版です。
 
     91. trinity.vim
 
        taglist, srcexpl, nerdtreeを同時に起動して
 
        VimがIDE画面のような画面になります。
 
     92. cscope-menu
 
        cscope用のメニューを表示してくれます。
 
     93. gtags.vim
 
        gtagsを使ってファイルを開けます。
 
     94. DoxygenToolkit.vim
 
        Doxygenコメントの入力をサポートしてくれます。
 
== Visual Studio Code ==
 
=== Keybind ===
 
==== 矩形選択 ====
Ref: [https://mitomito.hatenablog.jp/entry/2021/01/27/073000#:~:text=VS%20Code%E3%81%AE%E7%9F%A9%E5%BD%A2%E9%81%B8%E6%8A%9E%E3%81%A8%E7%9F%A9%E5%BD%A2%E8%B2%BC%E4%BB%98%E3%81%AE%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95%201%20%E3%83%9E%E3%82%A6%E3%82%B9%E3%81%A7%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%20shift%20%2B%20alt%20%2B,shift%20%2B%20alt%20%2B%20%E7%9F%A2%E5%8D%B0%E3%81%A7%E4%BB%BB%E6%84%8F%E3%81%AE%E7%AF%84%E5%9B%B2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%80%81%20%28or%20%E5%88%87%E3%82%8A%E5%8F%96%E3%82%8A%29%E3%81%99%E3%82%8B%20 VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog].
 
* s-alt-クリック
* c-s-alt-矢印
ジャンプ
 
* 括弧ジャンプ: C-S-\
 
=== Config ===
 
==== Default terminal ====
Ref: [https://stackoverflow.com/questions/44435697/change-the-default-terminal-in-visual-studio-code bash - Change the default terminal in Visual Studio Code - Stack Overflow].
 
[F1]-[Terminal: Select Default Profile]
 
=== cscope ===
cscope用のプラグインが何個かある。
 
* [https://marketplace.visualstudio.com/items?itemName=xulion.codescope scope4code - Visual Studio Marketplace]
* [https://marketplace.visualstudio.com/items?itemName=SeungukShin.cscope-code cscope-code - Visual Studio Marketplace]
 
scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
 
cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
 
Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。
 
=== Vim ===
 
* [https://marketplace.visualstudio.com/items?itemName=vscodevim.vim Vim - Visual Studio Marketplace]
 
VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
 
=== Extension ===
CSS
 
Tailwind CSS IntelliSense
 
==== PHP ====
Laravel Blade Snippets
 
===== PHP Intelephense =====
Ref: [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client PHP Intelephense - Visual Studio Marketplace].
 
VSCodeのPHPの補完拡張として人気が高い。
 
====== Quick Start ======
設置後、しておくべき設定がある。
 
* Go to <code>Extensions</code>.
* Search for <code>@builtin php</code>
* Disable <code>PHP Language Features</code>. Leave <code>PHP Language Basics</code> enabled for syntax highlighting.
 
VSCodeの [PHP Language Features] を無効にしておくとのこと。
 
後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。
 
====== Module ======
peclなどPHPの標準モジュールで一部認識できないものがある。
 
「[https://stackoverflow.com/questions/62258598/undefined-type-imagick-in-vscodes-intelephense php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow]」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
 
====== Coding ======
Ref: [https://beyondjapan.com/blog/2020/02/intelephense-vscode-php/ VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド].
 
intelephenseでコード補完を認識しやすい書き方というのがある。
 
まず、型をつけられるものはつける。<syntaxhighlight lang="php">
function superMethod()
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}
</syntaxhighlight>ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。
 
=== Other ===
 
==== Remote ====
[https://www.mathkuro.com/vs-code/upload-and-download-remote-file/ 【WinSCPはもう不要?】VS Codeのダウンロード/アップロード機能が便利すぎる!! | マスクロドットコム]
 
[https://code.visualstudio.com/docs/remote/remote-overview Visual Studio Code Remote Development]
 
公式拡張機能のVS Code Remote Developmentを使うと、リモートファイルをVS Codeで開いて、ドラッグドロップでファイル送受信ができるらしい。
 
== PhpStorm ==
 
=== Encoding ===
 
* [https://pleiades.io/help/phpstorm/encoding.html エンコード | PhpStorm ドキュメント]
* [https://pleiades.io/help/phpstorm/settings-file-encodings.html ファイルエンコーディング | PhpStorm ドキュメント]
 
パス単位で文字エンコーディングを設定可能。
 
[PhpStorm]-[Settings]-[Editor]-[File Encodings] から行う。
 
=== Scratch ===
[https://qiita.com/endam/items/cc2c4c2aee8d382acd9e 【New Year Calendar】君はPhpStormのScratch機能を知っているか #NewYearCalendar - Qiita]
 
メモなどの一時ファイルの作成機能。
 
[File]-[New Scratch File] からファイル形式を選んで作る。困ったらMarkdownで良いだろう。
 
作成したScratchファイルは [Project]-[Scratches and Consoles]-[Scratches] に格納される。
 
== PIM ==
[https://ja.wikipedia.org/wiki/Personal_Information_Manager Personal Information Manager - Wikipedia]
 
PIMという個人情報管理用アプリの分類がある。
 
* カレンダー
* アドレス帳
* 電子メール
* タスク管理
* メモ帳
* 音声メモ
* 電卓
* 時計
* 電子辞書


=== E-mail ===
===== winmail.dat =====
[https://winmaildat.net/ winmail.dat変換ツール(インストール不要)]


==== General ====
MS outlookなどで使われる添付ファイルの形式。


===== Naming =====
===== Naming =====

2025年1月9日 (木) 00:02時点における最新版

ソフトウェア開発作業全般

Other

ASCIIFlow: 画面構成図などの作成でテキストなので便利かもしれない。

Project

名簿付きの寄付

  • Vim: https://vim-jp.org/vimdoc-ja/sponsor.html
  • Vim (list): https://www.vim.org/sponsor/hall_of_honour.php
  • KDE: https://relate.kde.org/
  • KDE (list): https://relate.kde.org/civicrm/profile?gid=18&search=0
  • Conservancy (list): https://sfconservancy.org/sponsors/
  • Conservancy: https://sfconservancy.org/donate/

Kanboard

クローズ時に自動移動

[Configure project]-[Automatic actions]

  • action=[Move the task to another project]
  • Event name=Closing a task
  • Column=Done
  • Project=

これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。

Communication

Skype

すべてのエモーティコンのリストはありますか? - Microsoft サポート

Skyepで使用可能な絵文字の一覧。

Slack

チャンネル

https://slack.com/intl/ja-jp/help/articles/205239967-%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%99%E3%82%8B

一覧表示

[ホーム]-[チャンネル]-[管理する]-[チャンネル一覧] でチャンネル一覧を閲覧可能。

Confluence

ページの中で、 [作成] を選んでページを作ると、階層が勝手にできて、子ページへのリンクもできる。

ショートカットキー

キーボード ショートカット

https://ja.confluence.atlassian.com/doc/keyboard-shortcuts-139456.html

エディタ

ブロック フォーマット

Windows 操作 Mac
Ctrl + 0 Paragraph ⌘+ 0
Ctrl+ (1 ~ 6) (選択した番号の)見出しレベル ⌘+ (1—6)
Ctrl + 7 Preformatted ⌘+ 7
Ctrl + 8 Quote ⌘+ 8
Ctrl + Shift + B、または

* + Space

箇条書きリストを追加 ⌘ + Shift + B、または

* + Space

Ctrl + Shift + N、または

# + space

番号付きリストを追加 ⌘ + Shift + N、または

# + space

Ctrl + Shift + S Strikethrough ⌘ + Shift + S
Ctrl + Shift + Subscript ⌘ + Shift + ,
Ctrl + Shift + Superscript ⌘ + Shift + .
Ctrl + Shift + M Monospace ⌘ + Shift + M
Ctrl + \ Clear formatting ⌘ + \

豊富なフォーマット

CTRL + Shift + V

サファリのみ:Ctrl + Shift + Alt + V

書式設定なしでテキストを貼り付け ⌘ + Shift + V

Safari のみ:⌘ + Shift + Option + V

Ctrl+M Files and images ⌘+ M
Ctrl+K リンク([リンクの挿入] ダイアログが開く) ⌘ + K
Ctrl + Shift + D マークアップを挿入([マークアップの挿入] ダイアログが開く) ⌘ + Shift + D
Ctrl+Shift+A マクロ([マクロの選択] ダイアログが開く) ⌘ + Shift + A
Ctrl + Shift + O 次のインライン コメントに切り替え ⌘ + Shift + O
Ctrl + Shift + L 前のインライン コメントに切り替え ⌘ + Shift + L
CTRL + Shift + Z インライン コメントを閉じる ⌘ + Shift + Z
Ctrl + Shift + I ⌘ + Shift + I
Alt + 上矢印 行を上に挿入 Alt + 上矢印
Alt + 下矢印 下に行を挿入 Alt + 下矢印
Ctrl + Shift + X 行を切り取り ⌘ + Shift + X
Ctrl + Shift + C 行をコピー ⌘ + Shift + C
Ctrl + Shift + Y 行を上に貼り付け ⌘ + Shift + Y
Ctrl + Shift + ; 絵文字メニュー ⌘ + Shift + ;
CTRL + Shift + V 書式設定なしで貼り付け ⌘ + Shift + V
書式設定なしで貼り付け (Safari) ⌘ + Shift + Option + V
オートコンプリート

[] が勝手にリンクになるのが困る。

リンク、ファイル、マクロ、メンション、絵文字のオートコンプリート

https://ja.confluence.atlassian.com/doc/autocomplete-for-links-files-macros-mentions-and-emojis-249858190.html

オートコンプリートの無効化方法。

プロフィール画像を選択-[設定]-[エディター]-[☑️オートコンプリートの無効化]

ただ、オートコンプリートの丸ごと無効化は、便利な機能がなくなるので不味い。

一時的に回避したい場合、[の直前に何か文字があれば解釈されない。スペース開けて[があるとオートコンプリート扱いになる。


書式なしペースト

Confluenceで書式なしペースト(Ctrl+Shift+V)を有効にする #Confluence - Qiita [?]-[キーボードショートカット]-[General]-[▫️Enable General Shortcuts] にしてオフにすると有効になる。 [表の上部にペースト] と競合していたらしい。

マクロ

マクロ | Confluence Data Center 9.2 | アトラシアン製品ドキュメント

いくつか有用なマクロがある。

Other

パーマリンク

The Differences Between Various URL Formats for a Confluence Page | Confluence | Atlassian Documentation

Confluenceのページ新規作成時、パーマリンクが自動生成される。規則がある。

以下の条件にマッチしたら、padeId URLになる。それ以外は、タイトル名のURLになる。

  • [% & ? / ¥ ; " + :] などのようなURLの予約文字。
  • 非ラテン文字。
  • ページタイトル末尾が英数字以外の場合。
ページ履歴

ページ右上のメニュー-[ページ履歴]から履歴を確認できる。差分も確認できる。

ページ移動

ページの移動と順序の変更 | Confluence Data Center 9.2 | アトラシアン製品ドキュメント

ページ右上のメニュー-[移動]

Tool

General

Call tree

kcachegrindだったかな。

kscopeもこれか。

Doxygen+GraphVizで関数コールグラフ

kscope

https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code

https:/sourceforge.net/projects/kscope/

http:/www.lemis.com/grog/software/kscope.php

cscope

cbrowser/kbrowserというGUIもある。

cscopeの大文字小文字無視検索

http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html

DBを別にする必要がありそう。

expect

端末の手動操作を自動化するソフト。

* ^と$は使えない。代わりに、\nを使う。

* 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。

* expect文はawkみたいな感じ。

* ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。

expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"

https:/linuxjm.osdn.jp/html/expect/man1/expect.1.html

```

sh -eux <<-"EOT"

expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect aho {send echo aho} +x {send pwd/n}; expect /$; exit"

expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect + {send pwd/n}; expect /$; exit"

expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"

expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'

EOT

```

GNU screen

GNU Screenコマンドをつかってみる #screen - Qiita

screenコマンド実行後に、C-a押下後に対応するキーを押して各種操作を実行する。

キー操作以外に、コマンドも用意されている。C-a :でコマンドラインモードに入る。

特に重要な操作。

  • Help
    • C-a ?
    • Command:help
  • Window
    • C-a c/C-a C/Command:screen=Windowを生成。
    • C-a space/C-a n/C-a C-n/Command:next=次のWindowへ移動。
    • C-a p/C-a C-p/C-a C-h/C-a Backspace/Command:prev=前のWindowへ移動。
  • 画面分割: Regionを分割してそこにWindowを割り当てる。
    • C-a S=横分割
    • C-a |=縦分割
    • C-a TAB/Command:focus=分割画面の移動。
  • クローズ
    • C-a X/Command:remove=現在のRegionを終了。
    • C-a Q/Command:Only=現在以外のRegionを終了。
.screenrc
スタートアップメッセージ
startup_message off
スクロール

linux screen中にマウスホイールでスクロールする方法 - 技術メモ集

デフォルトだとマウススクロールなどに対応していない。以下の設定で対応でき、通常使用で問題なくなる。

termcapinfo xterm* ti@:te@
defscrollback 100000

Binary

.so

ソフトウェアの依存関係などの調査で.soファイルの分析を行うことがある。

.soファイルの中のシンボル探し

  • nm
  • ldd
  • string

Coding

タイムゾーン

タイムゾーン呪いの書 #timezone - Qiita

3文字形式は避けたほうが無難。

タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。

tz databaseのAsia/Tokyoなどの確実性が高い。

Regular Expression

正規表現。重要。覚えにくいが重要なものをメモしておく。

後ろからマッチ。cが置換対象。

Case

/[^c]*$/: cより右端

マッチの前後の挿入

https:/vim.fandom.com/wiki/Power_of_g

:g/GST_.*("/s/^/LOG(INFO) << "DEBUG";/r/

行頭・行末で引っ掛ける。

関数にログ
:%s/([^")]*)/) /([a-z]* /)*{/&/rLOG(INFO) << "/1";/r/g

考慮するケース

double currentTime() const override { return m_element->currentTime(); }

glob

重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。

使用可能な記号は以下3個。以下の3文字は\でエスケープできる。

  • ?: 任意の1文字にマッチ。
  • *: 任意の0以上の文字にマッチ。
  • [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。

ファイル名マッチ時には、追加で特殊なルールがある。

.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。

globで.ファイルを含めたい場合、工夫が必要 (PHP: glob - Manual)。

.[!.]* *

上記のように.ファイルのマッチとそれ以外を指定する必要がある。

.[!.]* は、...以外の..始まりのファイルにマッチする。

.*を指定すると、./..がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、.*だと. /..はマッチしない。

引用符のネスト

シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。

JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。

交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。

問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。

二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。

基本的な方法。

  1. 既存の一重/二重引用符などをバックスラッシュでエスケープ。
  2. 全体を一重/二重引用符で囲む。

何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。

[{"ke\y":"valu\e"}] を例として考える。

  1. {"ke\y":"valu\e"}
  2. エスケープ: {\"ke\\y\":\"valu\\e\"}
  3. 全体囲み: "{\"ke\\y\":\"valu\\e\"}"

これでOK。また何か考慮不足があればそのときに考える。

ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。

例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。

echo $(cat <<-'EOT'
{"ke\y":"valu\e"}
EOT
)

.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。

JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。

基本的な考え方がある。

  1. JSON value用に二重引用符"を\"で置換。
  2. \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
  3. JSON項目の二重引用符"を\"で置換。
  4. 全体を二重引用符"で囲む。

こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。

ケース変換

javascript - camelCase to kebab-case - Stack Overflow

キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。

encode

【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ

日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。

  • パーセントエンコーディング/URLエンコード: URLで使用不能な文字を%16進数で連結。
  • UTF-8
  • base64: 全データを「A-Z」「a-z」「0-9」「+」「/」の64文字で表現。文末に=を使うので実質は65文字。
  • HTMLエンコード: HTMLで特殊な意味を持つ文字を&lt;などに変換する。

Percent-encoding

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

上記文字はエンコードの対象外。

英数変換

string - PHP How to encode all characters with rawurlencode - Stack Overflow

変数名への変換などで、日本語や記号を英数字 [0-9a-zA-Z] に変換したいことがある。

こういう目的だと%エンコーディングが適している。

ただし、一部の記号を許可しているので、自前で変換する。

function encode_all($str) {
    $hex = unpack('H*', $str);
    return preg_replace('~..~', '%$0', strtoupper($hex[1]));
}

$str = 'big ƒüßchen';
print_r(encode_all($str));

Term

紛らわしい用語がある。

フレームワークの中にライブラリーも含めていいと思う。

Pythonのモジュールとパッケージとライブラリとフレームワークの違い」がわかりやすい。

フレームワークはライブラリーを含んでいる。ライブラリーで共通でいいと思う。

Category

ソフトウェア開発工程 - Wikipedia

ソフトウェアの分類、ページ分類時に役立つ。

  • 言語
  • ツール: 静的解析、テスト、文書など。
  • フレームワーク

MediaWikiのページ名は全体で固有が条件なので、言語名+分類名でページを作るといい。

  • PHP language
  • PHP tool
  • PHP framework

成功時連続継続処理

一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。

  1. 処理実行。
  2. 成功ならA、失敗なら終了。
  3. 処理実行。
  4. 成功ならA、失敗なら終了。

こういうパターン。いくつか実装方法があるが、while (true) のパターンが重複がなくてベストだと思う。

        /*
        // 無限ループで終了条件でブレイク
        while (true) {
            // 処理実行
            if (失敗) {
                break;
            }
            成功時処理
        }
        
        // do while
        do {
            処理実行
            if (成功時) {}            
        } while ();

        // for (初期化; 継続判定・終了判定; 成功時式) {
            処理実行
        }
        */

do-whileは成功・終了判定を2回書く必要がある。

forだと成功処理を式でしか書けない。成功処理を関数や即時実行関数式などで書くなら悪くはないし、ベストになりえる。

いや、成功時処理内の処理の結果次第で反復の終了条件などが追加で入るならNGになる。なので、やっぱりwhile(true)が無難。コード行数もそんなに変わらない。

これにさらに初回だけ、ヘッダーの取得、書き込み処理などが発生する場合、初回だけループの外でやるのがきれいだろうか?初回処理が2回登場することになるけれど。

offsetなどで初回の判定が反復内でできるから、それで分けるのがいいか?

        $offset = 0;
        while (true) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);

            $response = $service->getApiResultJson();
            // 終了条件: 戻り値が成功以外、か応答本体が1行 (ヘッダーのみ) の時。
            if (($currentReturnCode !== Raku2Config::EXIT_SUCCESS) || (substr_count($response, "\n") <= 1)) break;

            // 2回目からはヘッダー除去して書き込み。
            $start = strpos($response, "\n") + 1;
            $flat = FILE_APPEND;
            if ($offset === 0) {
                $start = $flag = 0;
                $path = stream_get_meta_data($fp = tmpfile())['uri'];
            }
            file_put_contents($path, substr($response, $start), $flag);
            $offset += $limit;
            sleep(3);
        }
        for ($offset = 0;
            ($currentReturnCode === Raku2Config::EXIT_SUCCESS) && (substr_count($response, "\n") > 1);
            (function() use (&$offset, $limit, $response) {
                // 2回目からはヘッダー除去して書き込み。
                $start = strpos($response, "\n") + 1;
                $flag = FILE_APPEND;
                if ($offset === 0) {
                    $start = $flag = 0;
                    $path = stream_get_meta_data($fp = tmpfile())['uri'];
                }
                file_put_contents($path, substr($response, $start), $flag);
                $offset += $limit;
                sleep(3);
            })()
        ) {
            $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [
                json_encode([
                    'dbSchemaId' => $table_info['dbSchemaId'],
                    'offset' => $offset,
                    'limit' => $limit,
                ])
            ]);
            $response = $service->getApiResultJson();
        }

character

BOM

UTF-8のBOM

\xef\xbb\xbf

この文字を先頭につけるとUTF-8のBOMになる。

Convert

IP/CIDR

// JavaScript
    /**
     * サブネットマスクをIPアドレス形式 (x.x.x.x/255.255.255.0) からCIDR形式 (x.x.x.x/24) に変換する。
     * @param {string} ipaddress - IPアドレス文字列 (x.x.x.x/x.x.x.x形式)。
     */
    toCIDR(ipaddress) {
      const [address, mask] = ipaddress.split('/')
      const segments = mask.split('.')
      const CIDR = segments
        .map((e) => Number(e).toString(2))
        .join('')
        .replace(/0*$/, '').length
      return address + '/' + CIDR
    },
    /**
     * サブネットマスクのCIDR形式 (24) をIPアドレス形式 (255.255.255.0)に変換する。
     * @param {number} cidr - ciderの数字。
     * @return {string} x.x.x.x形式のIPアドレス文字列。
     */
    cidrToIp(cidr) {
      const digit = 32
      const ip = ('1'.repeat(cidr) + '0'.repeat(digit)).substr(0, digit)
      return ip
        .match(/.{8}/g)
        .map((e) => parseInt(e, 2))
        .join('.')
    },

Algorithm

再帰処理

https://chatgpt.com/c/673d9bfe-2414-800b-9922-f94be6dbe950

配列の配列、オブジェクトのオブジェクトなど、再帰的な構造はけっこう遭遇する。

再帰関数で実装するほかに、スタックで処理する方法がある。

再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。

パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。

最初は再帰関数で実装して、後でボトルネックになったらスタックというのも手。

https://chatgpt.com/c/6745228f-8b20-800b-8a41-bdaece8c03f5

再帰関数とスタックの他に、JSONなどの文字列にシリアライズして、文字列処理で対応するという手もある。

JSONPath/XPathなどの方法もあるが、基本的には外部ライブラリーが必要。

シンプルなケース以外は、再帰関数で処理したほうが結局シンプルな感じがする。

Other

コメントの著者名

https://chatgpt.com/c/67469d8d-7e64-800b-b82d-8c74f4e13c08

GNU socialのソースコードのコメントに著者名が大量にあった鬱陶しい。

大規模プロジェクトになると、編集者が膨大になる。VCSに任せて、本文には記載しなくていいと思う。

git blameで行単位で編集者が分かる。

UML

Tool

https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628

What are the best UML tools for macOS? - Quora

  • デスクトップ
    • StarUML
    • ArgoUML
    • UMLet
    • OmniGraffle
    • edraw: 有料。
    • Umbrello
    • Modelio
  • クラウド
    • Visual Paradigm
    • Lucidchart: 有料。
    • Creately: 有料。
    • diagrams.net: モデルじゃない。
  • その他
    • PlantUML

UmbrelloとModelioはそれらと比較して何がよかったのだっけ?

Eclipse Papyrusが動作するならこれがいい。Eclipseは安定しているから、これのプラグインで動作するなら信頼できるだろう。

papyrusは一度試してダメだった気がするが。

Umbrello

Problem

altなどの重なり順番、アクティブの下になっちゃう

optの条件が表示されない。

Modelio

クラス図

  • 汎化 (generalization): 実線白矢印。継承。
  • 実現 (realization): 点線矢印。interfaceの継承。
  • 集約: 白ひし形。
  • コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
  • 関連: 実線矢印。メソッド内インスタンスなど。
  • 依存: 点線矢印。引数やローカル変数、返却値。

Papyrus

Papyrus Dowloads

Papyrus Documentation

Tutorial

公式の[A slide-ware tutorial on Eclipse Papyrus usage for starters (2010-10-01)]を参考に基本的な使い方を学ぶ。

[File]-[New]-[Papyrus prooject]

これでプロジェクトを作ると、以下が [Project Explorer] に作られる。

  • <project name>
    • <project name>
      • di: ツールメタデータ。モデル作成のエントリーポイント。
      • notation: 画像データ。
      • uml: UMLモデルデータ。

このdiをダブルクリックして描画を開始する。

1個のプロジェクトでいろんな図に対応していて、モデルを流用できる形になっている。悪くない。これを使う。

Design

Atomic Design

最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。

  • atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
  • molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
  • organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
  • templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
  • pages: ページ。テンプレートを使用したページ。

インターフェイスと抽象クラス

PHPでインターフェイスと抽象クラスを使う #PHP - Qiita

  • インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
  • インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。

インターフェイス

  • メソッド宣言のみ。
  • static/constの場合に限定して、メソッド定義、定数もOK。

Config class

アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange」で特によく議論されている。

  1. シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
  2. DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。

2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。

メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。

do-while/if

複雑なif文と相性がいい。

for whileの無限ループで最後にbreakでも同じか

do {
  if (true) break;
} while(false);

if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。

GoF

基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。

これにより、いろんなケースに同じコードで対応できる。

Factory Methodパターン

なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)

コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。

引数の内容に応じて、異なるクラスを作成する。

ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。

複雑でややこしいだけなので、基本的に使わなくてよいと思う。

Naming

camelCase

https://gnusocial.jp/notice/7694551

!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。

getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…

getMyVariable() vs myVariable()

getterとsetterの命名規則。

getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。

ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。

namePrefixed() vs prefixedName()

https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85

名詞+修飾語 (形容詞) の場合のメソッドの命名規則。name+修飾語が複数ある場合name+修飾語がいい。オブジェクト指向でnameをオブジェクトとして扱う形に近い。name.methodみたいな。

例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。

そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。

PHPでは以下のような命名規則が好まれる。

  • 動詞+修飾対象=getPrefixedName/isPrefixed()
  • 修飾対象+状態/修飾語=prefixdName

getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。

map

連想配列とかハッシュ、オブジェクトなどでキーバリュー形式のデータ構造を扱うことがある。そういう変数の命名規則。

map_[key]_[value] のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。

array/foreach

foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。

foreach (table as $row => $line)

その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。

いいえ。これは問題がある。ネストした場合などに命名規則を維持できない。

  • 配列、コレクション類: 複数形があるなら複数形。困ったらListの接尾辞。
  • 反復時。キーバリュー形式の場合、単数形_key/_value。valueだけの場合、単数形。また、_valueは単数形でもいいかもしれない。

上記の命名規則だとわかりやすい。

$rows = [[]];
foreach ($rows as $row_key => $row_value) {
  foreach ($row_value as $column_key => $column_value) {}
}


foreach ($row_list as $row_key => $row) {
   foreach ($row as $column_key => $column) {
   }
}


foreach ($rows as $row_index => $row_value) {
  foreach ($row_value as $column_index => $column_value) {
  }
}

value部分に単数形を使うと、検索時にkey部分もヒットして、作業しにくいかもしれない。基本はkey/valueの接尾辞がよいと感じる。

もっというなら、接尾辞の文字数が揃うので、keyよりindexのほうがよいかもしれない。ただ、indexは添え字の数字の意味合いが強いので、やっぱりkey/valueでいいか。

Function argument order

関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。

https://social.senooken.jp/notice/67270

うーん。今晩は,CODE COMPLETEでC言語の関数の引数の順番を調べたりしていて,勉強時間がないな…

int func(入力,変更,出力)

この順番。理由は,この順番で使うから。

memcpyとかは例外が多い。

x = bの語順からきているからとの憶測がある。

https://okwave.jp/qa/q4202225.html

DB

PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note

DBアクセスのモデル化。行をクラスとすると扱いやすい模様。

getterを作ったり、データの妥当性のチェックなどもできる。

select/insert/などはmapperでクラスとDB列名を対応付けて処理する。自前で実装する場合はこういうつくりがいいらしい。

データベース関係のデザインパターンがいくつかある。

  • Active Record
  • Data Mapper
Active Record pattern

テーブルレコードに対応するクラスを用意して、そのクラス自体にDB操作もさせる。

シンプルだが、複雑な操作が苦手。

エンティティーがテーブルと密接なため、例えばテーブル構造が変わった場合に大量に修正必要。

Ruby on Rails/Laravel+Eloquentなどで採用。

Data Mapper pattern

第14回 DataMapperの使い方 | gihyo.jp

テーブルのレコードをクラスにするのはARと共通。

ただし、DB操作用のクラスを用意してそちらでDB操作する。

その都合、1テーブルに2クラス必要。

User/UserMapperのような対応関係。

2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。

JOIN

Active RecordもData MapperもJOIN時の扱いが一番重要。単一エンティティーしか扱わないならどちらも同じ。

基本はエンティティーのプロパティーに持たせる感じ。

datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?

`DataMapper`パターンで`JOIN`を行う場合、エンティティの扱いは設計次第ですが、いくつかの注意点があります。`DataMapper`パターンは、データベースのテーブルとエンティティの間にマッピングを行い、エンティティはドメインロジックを持ち、データベースアクセスの責務を持たないことが特徴です。そのため、`JOIN`の処理をどの層で行うかを慎重に設計する必要があります。

以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。

      1. 1. マッパークラスでの`JOIN`実装

`JOIN`を伴う複雑なクエリが必要な場合、マッパーが直接`JOIN`を使って複数テーブルを組み合わせた結果を取得し、それを複数のエンティティとしてマッピングする方法があります。例えば、ユーザーと注文を持つシステムで、ユーザーとその注文を一緒に取得したい場合、`UserMapper`で`JOIN`を行い、結果セットを`User`と`Order`エンティティに分割してマッピングします。

```python

class UserMapper:

    def find_user_with_orders(self, user_id):

        sql = """

            SELECT * FROM users

            JOIN orders ON users.id = orders.user_id

            WHERE users.id = %s

        """

        results = self.db.execute(sql, (user_id,))

       

        user = User(results[0]['user_id'], results[0]['user_name'])

        orders = [Order(row['order_id'], row['product_name'], user) for row in results]

        user.orders = orders

        return user

```

この方法では、1つのSQLクエリで必要なデータをすべて取得し、エンティティのプロパティにそれぞれのデータを設定します。

      1. 2. リポジトリでの集約

`JOIN`を使わず、各エンティティを個別に取得した後、リポジトリが集約の役割を担う方法もあります。リポジトリが各エンティティの`Mapper`を呼び出し、必要なエンティティ同士を関連付けることで`JOIN`を再現します。例えば、まず`UserMapper`でユーザー情報を取得し、次に`OrderMapper`で該当ユーザーの注文を取得してエンティティ間で関連付けます。

```python

class UserRepository:

    def __init__(self, user_mapper, order_mapper):

        self.user_mapper = user_mapper

        self.order_mapper = order_mapper

    def get_user_with_orders(self, user_id):

        user = self.user_mapper.find(user_id)

        orders = self.order_mapper.find_by_user_id(user_id)

        user.orders = orders

        return user

```

UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。

結局、user.ordersみたいな感じで、エンティティーに外部テーブルのレコードを配列で持たせるつくりになる。

クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。

方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。

Other

1対1-多対多

プログラミング言語でデータの関連付けをすることがある。

1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。

多対多の場合。これも配列。二次元配列で基本は0要素目など。

$array[][]

Project

レガシープロジェクトの立て直し

https://chatgpt.com/c/67481a93-adc0-800b-81c4-20d763133002

1. 現状分析

(1) ソフトウェアの動作確認

現在の環境でアプリケーションを動作させる。

どの部分が機能していて、どこが問題かを確認する。

必要であればエラーログを確認する。

(2) 依存関係の調査

アプリケーションのライブラリやフレームワークのバージョンを調査。

サポートが終了しているもの、互換性が失われたものを特定。

(3) コードベースの状態評価

コードの品質 (可読性、設計、テストカバレッジ) を確認。

セキュリティリスクを特定する (例えば、脆弱性が放置されていないか)。

2. 計画立案

(1) ゴール設定

具体的な目標を設定 (例: パフォーマンス改善、保守性向上、セキュリティ強化)。

(2) 優先順位の決定

どの機能を維持し、どの機能を削除または置き換えるか決定。

ユーザーに直接影響を与える部分を優先。

(3) リスク評価とバックアップ

修正に伴うリスクを評価し、現行システムのバックアップを取得。

3. 環境整備

(1) 開発環境のモダナイズ

ローカル環境やコンテナ (Docker) を用意してテストを容易にする。

CI/CD パイプラインの整備。

(2) 依存関係の更新

サポートされていないライブラリやフレームワークをアップグレードまたは置き換える。

(3) セキュリティの確保

古いOSSの脆弱性を修正。

HTTPSの導入、認証強化、インプット検証など。

4. コードのモダナイズ

(1) リファクタリング

レガシーコードをよりモダンで可読性の高いコードに変換。

デザインパターンを適用して保守性を向上。

(2) テストの追加

ユニットテスト、統合テストを導入。

既存の機能が壊れないことを確認するための自動化されたテスト。

(3) フロントエンド/バックエンドの分離

必要に応じてモノリシック構造を分離し、モダンなアーキテクチャ (SPA、Microservices など) に移行。

5. 機能拡張とデプロイ

(1) 新しい機能の追加

必要に応じて、現代のニーズに合った新機能を実装。

(2) 運用環境でのテスト

新しい環境で徹底的にテストし、問題がないことを確認。

(3) 本番環境にデプロイ

ロールバック計画を準備しつつ、安全にデプロイ。

6. 継続的改善

(1) モニタリングの導入

エラーログやパフォーマンスを監視し、迅速に対応できる仕組みを導入。

(2) 定期的なアップデート

フレームワークやライブラリを継続的に更新し、レガシー化を防ぐ。

(3) コミュニティへの貢献

OSSとしての性質を活かし、変更内容をコミュニティに共有することでフィードバックを得る。

このプロセスを通じて、安定した動作を保ちながら徐々に近代化することが可能です。特に、「現状分析」と「環境整備」をしっかり行うことで、後続の作業がスムーズになります。

AI

対話AI

List

【2024年版】対話型AIサービスおすすめ11選を徹底比較!チャットボットとの違い・メリット・課題・選び方なども紹介 - NotePM

いろいろある。

Name
Bing
Perplexity AI
ChatGPT
Google Gemini

ChatGPT

Plan

ChatGPT | OpenAI

Free/Plusの2のプランがある。

Free Plus
金額 [USD/月] 0 20
機能 基本 アーリーアクセス
エンジン GPT-4o mini GPT-4/GPT-4o/GPT-4o mini
制限 - GPT-4oの5倍以上のメッセージ送信
その他 - データ分析、ファイルアップロード、ビジョン、Webブラウジング
画像生成 - DALL-E

送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。

Account

公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。

ChatGPTに会員登録する意味は何ですか?


ChatGPTに会員登録する主な利点はいくつかあります。

1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。

2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。

3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。

4. **プレミアム機能**: 一部のサービスでは、会員登録をすることで、より高度な機能やサポートが提供されることがあります。

5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。

興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。

自分の過去の質問の履歴を見れるだけでも便利かも。

方法
質問の分割

https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c

Q. chatgptで質問するとき、連続して質問すると、同じURLで複数の質問が表示される。リロードして質問を分けたほうがいいのか?

A. どちらでも問題ない。が、質問が関連しているなら同じチャットで継続したほうがいい。直前の質問も文脈を考慮できる。完全に話が異なるなら分けたほうが後で整理したり、URLを共有したときにわかりやすい。

感想
2024-11-14 Thu

https://gnusocial.jp/notice/7806505

!it !ai 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。

例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。

https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2

getRelatedというややマニアックなメソッドを教えてくれます[eloquent getrelated] で検索してもなかなかたどり着けないです。

こういう検索エンジンで検索しにくい質問で便利だなと思います。

検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。

大量の凡人健常者が取り組んだ方法論として決まりきったものは、記憶の問題、ただの神経衰弱です。こういうのを検索エンジンの改良版としてAIに任せるのはいい使い方だと思います。

個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。

同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。

一方、私みたいなキチガイのデータは少ないので、検索エンジンやAIに聞いても出てこないです。世界で自分だけのオリジナルに専念するのがたぶんいいです。

2024-11-19 Tue

https://gnusocial.jp/notice/7867350

!ai ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。

phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85

私はこのレベルの細かい疑問がすぐ浮かぶのです。これを人間にきくと、頓珍漢な回答だったり、そもそも回答してもらえないし、何ならこういう質問した私がなぜかキチガイ扱いされて、微妙な雰囲気になって、質問できなくなって、ストレスが溜まって、居づらくなって早期退職になるんです。意味不明です。ただの質問にお気持ちの配慮とか面倒なので。

この間、 @yuriha に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?

対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。

検索エンジンでも調べることはできますが、めちゃくちゃ時間かかるんです。自分で複数の意見をみつけて、頭の中で比較検討して整理するので。これを一瞬でやってくれるのが楽。途中のデータ整理、目視は単純作業に近いのです。他のことに頭使えます。

もはや技術とか、ただの暗記の神経衰弱は別にいらないです。一般企業の上長とか、士業のように、単純知識でマウント取るタイプの仕事はこれで確かに駆逐されます。どうせ対話AIのほうが賢いのだから。知識量で勝てるわけないです。全世界の情報の集積結果なんだから。

凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。

Shell

Shell Command Language

Compound Commands

Shell Command Language

Case Conditional Construct
case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac
  • 未マッチで終了ステータス0。
  • pattern部分: シェル展開が有効。他はglob。
  • |でOR検索相当。
  • 最後のパターンの;;は省略可能。if文のようにも使える。
  • 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。

BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。

ワイルドカード

ワイルドカードで.始まりのファイルをマッチさせたい。

以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。

echo {.*,*}

BOM

unicode - Adding BOM to UTF-8 files - Stack Overflow

ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。

printf '\xEF\xBB\xBF' > with_bom.txt

上記コードでBOMを最初に書き込んで、後は追記する。

awk

The Open Group Base Specifications Issue 7

変数

特別
  • NF: 列数。列の全表示などで使う基本的で重要な変数。
  • NR: 行番号。
スコープ

変数のスコープ

関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。

文/statement

  • actions
    • if/else
    • while/do...while/for
    • break/continue
    • delete
    • next
    • exit
  • output
    • print
    • printf

関数

組込関数
  • Arithmetic
    • atan2
    • cos
    • sin
    • exp
    • log
    • sqrt
    • int
    • rand
    • srand
  • String
    • gsub
    • index
    • length
    • match
    • split
    • sprintf
    • sub
    • substr
    • tolower
    • toupper
  • I/O
    • close
    • getline
    • system

print/printfは関数ではなく、statement/文扱い。

ヘッダー出力、列別最大長さ出力。

awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv

CSV

シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita

# csvparser.awk

## Usage
# awk -f csvparser.awk data.csv

# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
function callback(row, len, fields,  col, field) {
    for ( col = 1; col <= len; col++ ) {
        field = fields[col]
        gsub(/\\/, "&&", field)  # \ は \\ にエスケープする
        gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
        print row ":" col " " field
    }
}

BEGIN { row = max_idx = 0 }
{
    idx = 0
    sub(/\r$/, "")
    while ($0 != "") {
        if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
            fields[++idx] = ""
        } else if (match($0, /^["]/)) {
            fields[++idx] = substr($0, 2)
            for (;;) {
                if (getline == 0) exit 1
                sub(/\r$/, "")
                if (match($0, /^([^"]|["]["])*["](,|$)/)) break
                gsub(/["]["]/, "\"")
                fields[idx] = fields[idx] "\n" $0
            }
            fields[idx] = fields[idx] "\n"
        } else {
            exit 1
        }
        field = substr($0, RSTART, RLENGTH)
        $0 = substr($0, RSTART + RLENGTH)
        lastcomma = sub(/,$/, "", field) > 0
        gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
        fields[idx] = fields[idx] field
    }
    if (lastcomma) fields[++idx] = ""
    while (idx < max_idx) delete fields[max_idx--]
    callback(++row, idx, fields)
    max_idx = idx
}

awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。

tail -c +4 data/101543.csv | awk -f csvparser.awk 

Other

binary

POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita

バイナリーデータの読込はodコマンド。なければhexdump。

書込はprintf。

head/tailの-cはPOSIXで使えたか?

root

リダイレクト出力

sudo権限でリダイレクト処理を行ってファイルに書き込む方法

リダイレクトはログインユーザーの権限でなされるらしく、root権限のある場所にファイル出力できない。

teeコマンドでやる。

pwd | sudo tee out.dat

teeコマンド実行する側でsudoが必要。


ログインシェルの確認

第 10 章 動作環境のカスタマイズ (Solaris ユーザ ログインシェルはGUIログインでも内部的にある。ログインシェルが読みこむprofileファイルなどは、ログイン時に、1回だけ実行したい処理の記述場所として最適。 SHELL環境変数にログインシェルのパスが入っている。

echo $SHELL
/bin/bash

OSの判別

OSTYPE環境変数に値があるのでこれで判別する。 例えば以下の値が入っている。

linux-gnu
darwin23

これらを検知して判定する。

case $OSTYPE in
  linux*) echo 'linux';;
  darwin*) echo 'Mac';;
esac

Configure

profile

bash の初期化ファイル .profile, .bashrc, .bash_profile の使い分けと管理方針 - A Memorandum 環境変数など~/.profileに全部のシェルの共通設定を記述して、~/.bash_profileなどのログインシェルやbashrcなどで参照するのがいい。

cmd.exe

Control block

for

あくまでコマンド。

nest

ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。

bitsadmin

Windowsでのファイルダウンロードコマンド

Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。

書式:

bitsadmin /transfer <job name> <URL> <output path>

<job name>と<output path>は必須なので注意する。

certutil

Windowsでのハッシュの確認に使える。

certutil -hashfile file
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe):
e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb
CertUtil: -hashfile コマンドは正常に完了しました。

rlogin.cmd

コマンドキーの送信を自動化できる?

rem rlogin.cmd

@Echo off
Set SERVER=192.168.0.0
Set USERNAME=
Set PASSWORD=

Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%

実行中プロセスのパスの確認

出典: Show EXE file path of running processes on the command-line in Windows - Super User

wmic process get ProcessID,ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath
wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST

簡易編集モード/挿入モード

Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。

cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。

そのほか、 git log のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。

[□挿入モード] にすると回避できる模様。

Web

URL

クエリー配列

やり方がいくつかある。

  1. CSV文字列で受取後分割: https://www.sakdor.net/test/?var=1,2,3 explode(",",$_GET[var]);
  2. 配列添字
    1. http://www.sakdor.net/test/?var%5B%5D=1&var%5B%5D=2&var%5B%5D=3
    2. http://www.sakdor.net/test/?var%5Ba%5D=1&var%5Bb%5D=2&var%5Bc%5D=3
    3. http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3

データが決まっているならcsvがシンプル。

CGI

https://chatgpt.com/c/67634332-a3b8-800b-87a2-e21bd21a1cfc

WordPressなどのWebアプリだとファイル拡張子が登場しない。これはいくつかの仕組みが組み合わさって実現されている。

  1. パーマリンク設定 によるクリーンなURL構造の生成。
  2. .htaccess(Apache)リライトルール によるURLの書き換えとルーティング。
  3. index.php を起点とする動的な処理。
  4. テンプレート階層 に従って適切なPHPファイルを呼び出す。

.htaccessでindex.phpにリダイレクトして、index.phpから全て処理している。これにより省略できている。

同じ用に、アプリ側が対応していれば、index.fcgiに全部リダイレクトして、パスを解釈してくれるなら、/でのアクセスもできる気がする。

apache - How can I run a FastCGI script in root url (/ - without path)? - Stack Overflow

HTTP

RFC 9110: HTTP Semantics

Content-Disposition

Content-Disposition - HTTP | MDN

RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)

Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"

filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。

multipart/form-data

rfc7578

ファイルアップロード用のMIME type。

リクエストヘッダー

Content-Type: multipart/form-data; boundary=--hogehoge

リクエストボディー

--hogehoge
Content-Disposition: form-data; name="user_name"
Content-Type: text/plain

test
--hogehoge
Content-Disposition: form-data; name="email"

sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"

male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg

\xff\xd8\....
--hogehoge--

ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。

curlコマンドでPOSTする, 様々な形式別メモ |

curlでの送信理由。

-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。

curl -X POST -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

データとテキストを同時送信したい場合、-Fで複数指定する。

curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

curlだと上記のboundaryなどをうまくやってくれるのだと思う。

リクエストボディー全体をファイルデータにする場合。

curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg https://xxxxx.net/xxxxxx

IP address

出典: 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット

自宅サーバーを行う際、固定IPアドレスが必要になる。

取得方法がいくつかある。

  • 契約しているプロバイダでオプションとして申し込む方法
  • 固定IPアドレスに対応しているSIMを契約する方法
  • VPNを利用した固定IPアドレスの提供会社を利用する方法

VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。

Authentication

認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。

Basic認証

出典: Basic認証 - Wikipedia

Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。

GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic cm9vdDpwYXNzd29yZA==

盗聴や改ざんが簡単だが、シンプルという利点がある。

Basic認証のキャッシュを削除する(ログアウトする) | DevelopersIO

ログアウト時は、hoge@domainのようにパスワードを省略した任意のユーザー名でログインを試みて既存のログイン状況を上書きする模様。

Digest認証も共通。

Digest認証

Basic認証・Digest認証・Form認証をざっくり理解 #Security - Qiita

HTTP標準の認証。Basic認証とほぼ同じ。ただし、パスワードをハッシュ化している。そのため、DBのパスワードが流出した場合に比較的安全。

OAuth

Ref

OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。

以下が登場人物。

  • resource owner: あるサイトのユーザー。
  • resource server: あるサイトのユーザーのデータの保有サーバー。
  • clent: クライアントアプリ。リソースサーバーのデータを使用したい。
  • authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。

アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。

処理の流れ。

  1. client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
  2. client<-resource owner: Authorization Grant。
  3. client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
  4. client<-authorization server: Access Token
  5. client->resource server: Access Token。アクセストークンでアクセス。
  6. client<-resource server: Access Token

Consumer Key/Secret: アプリ識別用のID/PW。

Access Token: サイトにアクセスするためのパスワード。

API

複数レコードの登録

複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ

既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?

REST WebAPIのプラクティス | yamarkz.com

delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。

パラメーター

json - REST API Best practices: args in query string vs in request body - Stack Overflow

パラメーターの指定に3種類ある。

  1. リクエストボディー
  2. クエリー
  3. パス

パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。

ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。

この原則に従うとシンプルだろう。

  • URIには長さの制限がある。
  • ボディー
    • 引数が非常に多い場合。
    • 画像などバイナリーデータ。
    • キー・値構造を持たない場合。
  • クエリー文字列
    • 引数を簡単に確認できる。
    • 共通の引数の場合。

検索機能のGET/POST

検索機能にGETとPOSTのどちらを使うか?という議論がある。

データ登録するわけなじゃないのだから、GETがいいんじゃない?

POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。

GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。

ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。

レート制限対策

いろいろ方法がある。

  • cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
  • 配列を利用して、1回のリクエストでまとめて取得する。
  • インターバルを設ける。
  • HTTP 429/413を検知して、リトライする。

指数関数的バックオフ

wait_interval = base * 2^n +/- jitter
  • wait_interval は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。
  • base は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。
  • n は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、nの値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。
  • jitter は 0 から base の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算し wait_interval の合計に加算するか減算するか、ランダムで選択してください。

バックエンドとフロントエンドの分離

https://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45

SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。

SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。

SSRの利点。

  • SEO
  • 初期表示。
  • 匿名。

SSRの課題。

  • サーバー負荷: データとHTML作成を同時に行うから。
  • 分散困難:

キャッシュの活用がポイントになるとのこと。

Network

ssh

ssh-addの自動登録

ssh agentに秘密鍵の登録は以下のコマンド。

ssh-add <秘密鍵のpath>

ただし、上記コマンドは再起動すると登録が消えるので毎回必要。

~/.ssh/configに以下の内容を記入しておくと、次回からkeychainから自動で読み込まれるらしい (macOS で再起動しても ssh agent に秘密鍵を保持させ続ける二つの方法 #SSH - Qiita)。

Host *
  UseKeychain yes
  AddKeysToAgent yes

うまくいかなかった。

ssh-addをPC起動する度に自動的に実行させるための設定 | AIFAN

id_rsaの場合はIdentityFileを省略できるが、それ以外は指定が必要な模様。

Host *
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519
ssh経由でのリダイレクト出力

bash - How to remotely write to a file using SSH - Super User

ssh経由で標準入力内容からファイルをリダイレクトで作成したいことがある。

sshのコマンド部分を文字列にすればOK。

ssh user@remotehost -T "cat > /remotefile.txt" <<-EOT
Some text
EOT

-Tで擬似端末を無効にしている。

パスフレーズの省略

SSH多段接続時とgit cloneでSSH鍵参照時に、パスフレーズを要求される。毎回要求されるのが手間。これを省略する方法がある。 ~/.ssh/configに以下の設定を記述する。

Host *
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_ed25519
  • AddKeysToAgent=yesにすると、ssh-agentの実行時に自動的に鍵を追加する。
  • UseKeychain=macOS専用。OSのキーチェーンからパスフレーズの検索を試みる。
  • IdentityFile=SSH秘密鍵の絶対パス。デフォルトは~/.ssh/id_rsa。

上記3点で自動入力を試みる。 macOSで行う分には上記だけでパスワードは聞かれない。これをリモートでもやりたいなら、ssh-agentに登録が必要。 ログイン時に1回実行してくれたらいいので、ログインシェルの設定の~/.bash_profileに以下を記述。

echo 'ssh-add --apple-use-keychain' >>~/.bash_profile

これで端末の起動時に鍵を自動登録してくれるので、リモートでもパスフレーズを要求されない。

ssh_config

ssh_config(5): OpenSSH SSH client config files - Linux man page

重要な設定・構文がある。

TOKENS

macのman ssh_configに詳しい。

使用可能な指令が限定されている。

HostName (Macのみ)

  • %h=リモートホスト名。Hostの指定部。
  • %p=リモートポート。
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

ssh example.comなどを実行すると、IPアドレスの振り直しなどで、ホストの公開鍵が変わっていた場合、中間者攻撃への対策として失敗する。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:.
Please contact your system administrator.
Add correct host key in /Users/z.ken.senoo/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/z.ken.senoo/.ssh/known_hosts:1
Host key for [example.com]:3023 has changed and you have requested strict checking.
Host key verification failed.
Connection closed by UNKNOWN port 65535
Connection closed by UNKNOWN port 65535

$HOME/.ssh/known_hostsの該当行を削除すれば解決する。以下のコマンドでも対応してくれる。

ssh-keygen -R example.com

curl

HTTPの通信のコマンドラインでの確認でよく使う。

Basic

curl - Tutorial

  • -X: メソッド指定
  • -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users

JSONで送信する場合、ヘッダー指定が必須。

*-F: multipart/formのform指定。

curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html"
  http://www.example.com/postit.cgi

@でfilename相当の指定。;でmime typeも指定できる。

@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。

curl: (60) SSL certificate problem: self-signed certificate

Ref: curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI.

--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。

curl: Failed writing body

pipe - Right After piping to "head"/"tail": "curl: (23) Failure writing output to destination" - Ask Ubuntu

以下のようにhead -n 1を指定するとcurlがエラーを出力する。

curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN"         -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}"         https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0 | head -n 1
curl: Failed writing body

curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。

対策は、curl -sで出力を抑制するとのこと。これで解決。

Teleport

踏み台サーバー (Jump server/Jump host) をよりよく管理するためのサーバーソフトウェア。

アクセスログなどを一元管理できる。商用版とオープンソース版がある。

基本的にteleportのサーバーを一度経由して、各種の踏み台サーバーにアクセスする。経由先が1個増えるが、そのおかげで監査ログを取得できたり、権限などを一括管理できる。

ただ、teleportで監査ログを残すには、基本的にtshを経由する必要があり、既存のIDEなどのssh想定のソフトだと工夫が必要。tsh経由でやったり、rsyncで間にtshを挟むような工夫が必要。

tsh

teleportのコマンドラインクライアント。

tsh loginでteleportにログインする。

環境変数

tsh CLI reference | Teleport Docs

  • TELEPORT_PROXY: teleportプロキシーサーバーのアドレス。重要。
ProxyJump+ProxyCommand

How To Use SSH ProxyJump and SSH ProxyCommand

https://goteleport.com/blog/ssh-proxyjump-ssh-proxycommand/

~/.ssh/config のProxyJumpとProxyCommandの違いを整理する。

どちらも中間サーバーを経由したリモートサーバーアクセスの指令。

  • ProxyJump: 最も簡単な方法。OpenSSH v7,5以上で使用可能。中間サーバーでポート転送対応が前提条件。ProxyJumpは内部でProxyCommandを使う。
  • ProxyCommand: ProxyJump搭乗前の方法。中間サーバーを介して標準入力と標準出力を転送して機能。

ProxyJumpの方が現代的だが、ProxyCommandの方が柔軟性が高い。

ProxyJumpの使用例。

ssh -J <jump server> <remote server>ssh -J <jump server1>,<jump server2>,<jump server3> <remote server>

ProxyCommand

ssh -o ProxyCommand="ssh -W %h:%p <jump server>" <remote server>

~/.ssh/configの例。

Host remoteserver

 HostName 192.168.200.200

 User dev

 IdentityFile ~/.ssh/<your_key>

 Port 2048


 ## sample for ProxyJump

 ProxyJump user@<jumpserver>


 ## sample for ProxyCommand

 ProxyCommand ssh -W %h:%p <jumpserver>

ssh remoteserver で<jumpserver> 経由でremoteserverに接続できる。

一般的に、ProxyJumpが推奨される感がある。ただ、teleportを導入している場合、ProxyJump/ProxyCommandを使うと、tshを経由していないのでteleportにログが残らないらしい。

tsh経由ssh

ProxyJump/ProxyCommandを使わない場合、以下の形式でtshを使ってアクセスするのが基本。

tsh ssh 踏み台サーバーホスト名

tsh sshでteleportサーバーが管理している踏み台サーバーが見えるので、そこに接続できる。tshの後のsshは基本的に通常のsshと同じなので、sshの後にsshのコマンドを連鎖でき、対象サーバーにも一発でアクセスできる。

tsh ssh -At <jump host> ssh -A <target host>

-tでttyに繋いで標準入出力を接続。-Aはフォワーディング。ローカルのssh-addの情報などを連携できる。

<jump host>の~/.ssh/configを用意しておくことで、<target host>にホスト名を指定したりできる。

ProxyJump/ProxyCommandと異なり、これだとちゃんとログを残せる。

tsh経由scp

tsh経由の踏み台サーバーへのファイル転送はやや工夫が必要。

tsh scpというコマンドが一応ある。が、これはネストなどには未対応。やる場合、以下のように2回実行になる。

FR=test.file TO=/path/to/test.file
tsh scp $FR <jump host>:$TO; tsh ssh -At <jump host> scp $TO <target host>:$TO

高ではなく、rsyncを使えば一発でいける。

rsync -e "tsh ssh -A <jump host> ssh" ./test.file <target host>:~/

これが基本。

PhpStorm

JetBrains SFTP | Teleport Docs

teleportの公式にマニュアルがあるが、記述が非常に不親切。これだと踏み台サーバーにしかアクセスできない。その先にアクセスできない。

多段SSHの設定を残しておいて、ファイル転送だけrsyncで行う形になる。

PhpStormのSSH configurationsのホスト名がスクリプトの引数に渡されるので、踏み台からAWSにsshでログインするホスト名やパソコンの~/.ssh/configのHostとの一致必要な点に注意する。

USERNAME=
IPV4=
VPCID=
cat <<-EOT >>~/.ssh/config
Host $VPCID
  ForwardAgent yes
  User $USERNAME
  ServerAliveInterval 30
  SendEnv -LC_* -LANG
  ProxyJump $USERNAME@teleport.security:3023
   
Host $USERNAME
    ForwardAgent yes
    ProxyJump $VPCID:22
    User $USERNAME
    Hostname $USERNAME.example.com
    ServerAliveInterval 30
    SendEnv -LC_* -LANG
   
Host $USERNAME.$VPCID
    # for automatic upload by PHPStorm
    LocalForward 22224 $USERNAME.$VPCID:22
    # for XDebug
    RemoteForward 9000 localhost:9000
    ForwardAgent yes
   
Host db-*
  HostName $IPV4
  LocalForward 3307 localhost:22
  ProxyCommand ssh $VPCID -W %h:%p
  ForwardAgent yes
   
Host *
    AddKeysToAgent yes
    PasswordAuthentication no
    User $USERNAME
    ForwardAgent yes
    ServerAliveInterval 30
    IdentityFile ~/.ssh/id_ed25519
    # for macOS
    UseKeychain yes
EOT

こんな感じの多段SSHの設定を用意。 踏み台サーバーにも同じホスト名でアクセスできるように、以下のような内容の~/.ssh/configをまだならば設定しておく。

AWS_HOSTNAME=

IPV4=

VPCID=

tsh ssh -A $VPCID "cat >>~/.ssh/config" <<-EOT

Host $AWS_HOSTNAME

 HostName $IPV4

EOT


rsync executable

rsyncで使用する (-eオプション)、以下の内容のシェルスクリプトを作成して実行権限を付与して任意の場所 (例: ~/project/tsh_ssh.sh) に配置する。

cd ~/project/

cat <<-'EOT' >tsh_ssh.sh

tsh ssh -A <jump host> ssh $@

EOT

chmod +x tsh_ssh.sh


PhpStorm設定

PhpStormで以下を設定する。

  • [Tools]-[Deployment]-[Configuration]
  • [+]-[SFTP]
  • [Create New Server]-[New server name: 任意の名前 (例=rsync)]-[OK]
  • [Connection] タブを以下に設定。
    1. Type=SFTP
    2. SSH configuration=以下を設定。
      1. Host: <ホスト名> (例: ~/.ssh/configと踏み台サーバーの~/.ssh/configのホスト名と同じにする)
      2. User name: ユーザー名
      3. Port: 22
      4. Authentication type: OpenSSH config and authentication agent
    3. Root path=転送先のベース。
    4. [☑️Use Rsync for download/upload/sync]
    5. Rsync Settings=以下を設定。
      1. Shell executable path=tsh_ssh.shのパス (例=~/project/tsh_ssh.sh)
  • [Mappings] タブを以下に設定。
    1. Local path: ローカルパソコンのディレクトリー
    2. Deployment path: /
    3. Web path: /
  • [Settings]-[Build, Execution, Development]-[Development]-[Options]-[Upload changed files automatically to the default server]=[On explicit save action]
    1. ☑️Delete remote files when local are deleted

以上で完了。後は同期したいファイルをPhpStormで開いて、右クリック-[Deployment]-[Upload to]/[Download from] でファイル転送できる。

[☑️Use Rsync for download/upload/sync] のチェックを外せば、rsyncを使わないファイル転送になる。

Wireshark

TLS

Ref: SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー.

Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。

[Preferences]-[Protocols]-[TCP] を選ぶ。

  • ☑Allow subdissector to reassemble TCP stream
  • ☑Reassemble out-of-order semgemnts

上記をチェックしておく。デフォルトでチェックされていた。

続いて、セッションごとのPre-Master Secretを登録する。

Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。

以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。

export SSLKEYLOGFILE=/tmp/sslkey.log

Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。

Security

DoS攻撃

いくつか対策方法がある。

サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。

攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。

バリデーションの実装

基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。

ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。

二重送信

submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。

  1. ボタン連打
  2. ブラウザーバック
  3. リロード (PRG)

項目ごとにすべき対策が異なる。

連打

基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。

似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。

$("form").submit(function() {
  var self = this;
  $(":submit", self).prop("disabled", true);
  setTimeout(function() {
    $(":submit", self).prop("disabled", false);
  }, 10000);
});

停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。

Browser

Chromium

Extension

Chromme系で愛用拡張機能を列挙する。

devtool/開発者ツール

イベントリスナー

要素に設定されているイベントを調べよう - ゆずめも

[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。

イベント監視

How to find out which JavaScript events fired? - Stack Overflow

monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。

Network conditions

開発者ツールの[Network]タブを開いてリロードしても、[No internet]と表示されることがある。

これはオプション設定の問題。上のツールバーの[Disable cache]の右が[Offline] だとこうなる。これを[No throttling]にすると解決する。クリックミスだと思われる。

Safari

Windows Safari

一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。

開発者ツール

PCでスマホサイトを見る方法 – Safari編|東京渋谷のWeb制作会社・ホームページ制作会社|株式会社イー・バード

Safariの開発者ツールは癖がある。

[設定]-[詳細]-[☑️Webデベロッパ用の機能を表示]

[開発]-[レスポンシブデザインモードにする]

Other

Tool

いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。

localhost

RFC 6761 で規定。RFC 2606で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。

IPv4=127.0.0.1/IPv6=::1とされている。

Shared Host

Free

無料で使用可能な共用ホスティングサービスがある。

スタードメイン無料サーバー

ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。

無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~

jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。

  • ディスク容量 20GB
  • DB 1GB

ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。

CORESERVER

メール

情報

ルールが特殊なので注意する。

ゴミ箱に振り分ける場合。

順1 で[./.Trash] を指定

順2

  • 条件:  [.*]
  • 処理:  ./、に振り分ける

条件部分には正規表現が使えるように見える。

破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。

カスタムフィルターにくせがある。

  • エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」

Value Domain ネットde診断 byGMO

2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。

CGI

CORESERVERでのCGIの設定方法がある。

CORESERVERのFastCGI版PHPとCGI版PHPの設定方法
項目 FastCGI CGI
バージョンの変更 管理画面 .htaccess内の

AddHandler application/x-httpd-phpcgiXX .php

設定ディレクトリー /virtual/<username>/public_html/.fast-cgi-bin/
CGIの実行ファイル phpXX.fcgi phpXX.cgi
PHPの設定ファイル phpXX.ini php.ini
設定の反映タイミング バージョン切替時 即時

~/public_html/.fast-cgi-bin/のphpXX.fcgi phpXX.cgiがCGIの実行ファイル。このファイルか最後の行のexecのパスを変更すると、自前コマンドに変更可能。

FastCGIは管理画面からバージョンを変更したタイミングで反映される。ただ、ファイル拡張子が.phpじゃないとこのFastCGIが実行されない模様。

CGIは.htaccessに以下の内容を記述してCGI板PHPのバージョンを指定する。

AddHandler application/x-httpd-phpcgiXX .php

cgiのファイルには実行権限が必要。

chmod +x py.py

拡張子がないとダメな模様。加えて、.htaccessに以下の記述。

AddHandler cgi-script .py

これでpy.pyで動作はする。

拡張子じゃなくてファイル名で実行したい場合、SetHandlerでしていする (AddType, AddHandler, SetHandlerの違い – senooken JP)。

<FilesMatch py$>
    SetHandler cgi-script
</FilesMatch>

これでpyでもアクセスできる。

FastCGI版の場合、以下のような設定でファイル名でマッチさせれば実行できそうな気もするが。

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

500

<FilesMatch gnusocial$>
        SetHandler application/x-httpd-php
</FilesMatch>

pythonがphpとして認識され、テキストがそのまま表示される。

SetHandler fcgid-scriptにしたらFastCGIで動作する。プログラムがFastCGI対応になっている必要がある。

<FilesMatch gnusocial$>
        SetHandler fcgid-script
</FilesMatch>

Analytics

Exam

## About

https://gnusocial.jp/notice/4506679

### 全般

- マーケティング・ビジネス実務検定

- IMA検定

- Web検定

- ネットマーケティング検定

### 解析系

- ウェブ解析士

- GAIQ

- 統計検定

- Webアナリスト検定

GAIQが無料だしどうせ使うからいいかな。

https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/

https://www.plan-b.co.jp/blog/seo/12792/

## URL

- https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/

- https://mynavi-creator.jp/blog/article/qualification-for-web-marketer

- https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html

- https://digitor.jp/textbook/web-analytical-qualification/

Tool

サイト分析用のツールがいくつかある (2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】)。

  • SimilarWeb
  • Ubersuggest
  • ahrefs
  • Googleキーワードプランナー

閲覧数取得

出典: GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN

  • [行動]-[サイトコンテンツ]-[全てのページ]
  • [表示する行数]=5000
  • [エクスポート]=TSV

流入元特定

会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。

こんにちは。

探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。

・自由形式レポートを作成

・セグメント作成 > ユーザーセグメント

・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定

・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存

・探索レポートにセグメントを適用

・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列

・指標:セッション

ご確認よろしくお願いいたします。

※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。

 開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。

PMProでも似たような回答。

Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session.

Server

httpd

Apache HTTP Server

About

httpdの利用可能な情報。

https://chatgpt.com/c/6761f851-df0c-800b-86e9-1624b458d66d

# 使用可能な指令一覧
apachectl -L
httpd -L

# 使用可能なモジュール一覧
apachectl -M
httpd -M

.htaccessで使用可能な指令の一覧。

.htaccessで使用可能な指令一覧 – senooken JP

Operation

サーバーの稼働や状態確認などで重要な操作がいくつかある。systemd前提。

ログ・状態確認。

sudo systemctl status apache2

sudoをつけないと詳細ログを確認できない。

sudo systemctl restart apache2
sudo systemctl start apache2
sudo systemctl stop apache2

Access Control

DoS攻撃対策などで重要な設定。

mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。

基本構文は以下。

Require host <address>
Require ip <ip address>

1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。

Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。

mod_cgi

mod_cgi - Apache HTTP Server Version 2.4

CGIプロトコルのApacheモジュール。cgi-scriptにハンドラーを割り当てるとCGIとして扱う。

mod_fcgid

mod_fcgid - Apache HTTP Server Version 2.5

FastCGIプロトコルのApacheモジュール。AddHandlerかSetHandlerでfcgid-scriptハンドラーに割り当てられると、FastCGIとして処理される。

プログラム側もFastCGIに対応している必要がある。

Error

sudo systemctl status apache2
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/apache2.service.d
             └─privatetmp.conf
     Active: failed (Result: exit-code) since Fri 2024-12-06 15:09:28 JST; 12s ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 38461 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)

Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: [Fri Dec 06 15:09:28.259153 2024] [core:warn] [pid 38464] AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00112: Warning: DocumentRoot [/home/gree/frontend/greenet/htdocs_net] does not exist
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00526: Syntax error on line 7 of /etc/apache2/conf-available/rewrite-greenet.conf:
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: RewriteRule: unknown flag 'UnsafeAllow3F'
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: Action 'start' failed.
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: The Apache error log may have more information.
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Control process exited, code=exited, status=1/FAILURE
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Failed with result 'exit-code'.
Dec 06 15:09:28 z-ken-senoo systemd[1]: Failed to start The Apache HTTP Server.
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8

NameVirtualHost指令が廃止予定なので、行を削除して対応する。

AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.

DefaultTypeはnone以外意味がなく、警告表示になる模様。

.htaccess

directive

.htaccessで使用可能な指令一覧 – senooken JP

.htaccessで使用不能なよく登場して誤解する指令を整理しておく。

  • Alias
  • ScriptAlias
  • Directory/DirectoryMatch
  • Location/LocationMatch

逆にOKなもの。

  • Files/FilesMatch

E-mail

[サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]

MailHog: Go言語製のメールサーバーソフト。

Debian

PHP8

[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](https://computingforgeeks.com/how-to-install-php-on-debian-linux/)

Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。

sudo apt update

sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2

PHPパッケージを追加する。

echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list

wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -

sudo apt update

これでPHP8を参照できるので、インストールする。

sudo apt install php8.2

[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](https://tecadmin.net/switch-between-multiple-php-version-on-debian/)

インストールしたら、PHPのバージョンを切り替える。

a2dismod php7.4

a2enmod php8.2

sudo systemctl restart apache2

php 8.2にするとこういうエラー。

[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error:  Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n  thrown in /var/www/gnusocial/public/index.php on line 104

念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。

<https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。

私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?

alternative

Ref: DebianAlternatives - Debian Wiki.

OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。

sudo update-alternatives --display vi
sudo update-alternatives --config vi

オプションとコマンド名を指定することで、現在の実体と更新ができる。

XAMPP

ポート番号変更

Xamppでポート競合を防ぐ方法 #PHP - Qiita

XAMPP Control PanelのConfigから変更可能。

phpmyadminはConfigのphpmyadminで、Servers.portを追加する。

Vim

Other

Async

https:/github.com/skywind3000/asyncrun.vim

asyncrun.vimは1個のバックグラウンド処理しか対応していない。

https://github.com/skywind3000/asyncrun.vim/issues/12

vim-dispatchならいけるのか?

Binary

vim-jp » Hack #133: バイナリファイルを編集する

grep

非同期でgrepする方法。

https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously

https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/

Vim 8の非同期APIはプラグイン用。

* https://github.com/mhinz/vim-grepper

* https://github.com/skywind3000/asyncrun.vim

* https://github.com/tpope/vim-dispatch

https://wonderwall.hatenablog.com/entry/2017/10/09/210000

asyncrun.vimでやるのがよさそう。

AnsiEsc

* https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors

* https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly

本家は太字に対応していないのでこちらがいいかな。

- https:/github.com/powerman/vim-plugin-AnsiEsc

ただし、こちらはgvimでクリック時にカーソル位置がずれる。

program

C

ワシのVimプラグインは百八式まであるぞ - daisuzu's notes

【C/C++】

     87. a.vim

        C/C++のヘッダとソースを切り替えます。

     88. c.vim

        C/C++のテンプレートやイディオムの入力をサポートしてくれます。

     89. CCTree

        cscopeを使って関数のコールグラフを表示してくれます。

     90. Source-Explorer-srcexpl.vim

        ソース解析ツール、Source InsightのVim版です。

     91. trinity.vim

        taglist, srcexpl, nerdtreeを同時に起動して

        VimがIDE画面のような画面になります。

     92. cscope-menu

        cscope用のメニューを表示してくれます。

     93. gtags.vim

        gtagsを使ってファイルを開けます。

     94. DoxygenToolkit.vim

        Doxygenコメントの入力をサポートしてくれます。

Visual Studio Code

Keybind

矩形選択

Ref: VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog.

  • s-alt-クリック
  • c-s-alt-矢印

ジャンプ

  • 括弧ジャンプ: C-S-\

Config

Default terminal

Ref: bash - Change the default terminal in Visual Studio Code - Stack Overflow.

[F1]-[Terminal: Select Default Profile]

cscope

cscope用のプラグインが何個かある。

scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。

cscope-codeはシンプルだが動作した。こちらを当分使うことにする。

Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。

Vim

VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。

Extension

CSS

Tailwind CSS IntelliSense

PHP

Laravel Blade Snippets

PHP Intelephense

Ref: PHP Intelephense - Visual Studio Marketplace.

VSCodeのPHPの補完拡張として人気が高い。

Quick Start

設置後、しておくべき設定がある。

  • Go to Extensions.
  • Search for @builtin php
  • Disable PHP Language Features. Leave PHP Language Basics enabled for syntax highlighting.

VSCodeの [PHP Language Features] を無効にしておくとのこと。

後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。

Module

peclなどPHPの標準モジュールで一部認識できないものがある。

php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。

Coding

Ref: VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド.

intelephenseでコード補完を認識しやすい書き方というのがある。

まず、型をつけられるものはつける。

function superMethod()
{
    /** @var AwesomeService $awesomeService */
    $awesomeService = $this->app->make(AwesomeService::class);
    $awesomeService->awesomeMethod();
}

ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。

Other

Remote

【WinSCPはもう不要?】VS Codeのダウンロード/アップロード機能が便利すぎる!! | マスクロドットコム

Visual Studio Code Remote Development

公式拡張機能のVS Code Remote Developmentを使うと、リモートファイルをVS Codeで開いて、ドラッグドロップでファイル送受信ができるらしい。

PhpStorm

Encoding

パス単位で文字エンコーディングを設定可能。

[PhpStorm]-[Settings]-[Editor]-[File Encodings] から行う。

Scratch

【New Year Calendar】君はPhpStormのScratch機能を知っているか #NewYearCalendar - Qiita

メモなどの一時ファイルの作成機能。

[File]-[New Scratch File] からファイル形式を選んで作る。困ったらMarkdownで良いだろう。

作成したScratchファイルは [Project]-[Scratches and Consoles]-[Scratches] に格納される。

矩形選択

複数のカーソルと選択範囲 | PhpStorm ドキュメント

方法がいくつかある。

  • Cmd-Shift-8
  • Option-Shift-Middle

PIM

Personal Information Manager - Wikipedia

PIMという個人情報管理用アプリの分類がある。

  • カレンダー
  • アドレス帳
  • 電子メール
  • タスク管理
  • メモ帳
  • 音声メモ
  • 電卓
  • 時計
  • 電子辞書

E-mail

General

winmail.dat

winmail.dat変換ツール(インストール不要)

MS outlookなどで使われる添付ファイルの形式。

Naming
RFC
  • webmaster
  • support
  • info
  • service
  • pr
  • billing
  • 氏名

売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース

infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum

rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt

SuperTAINS News No.23 [Page.5]

【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki

公開用のメールアドレス。何にしようか考えていた。

RFC 2142でいくつか推奨されている。

info@ support@ answer@ inquery@ contact@ pubic@

contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。

develop

GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:13:28 JSTGNU social JP管理人GNU social JP管理人
使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。

メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。

どう使い分けるのがよいでしょうか?案↓
GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:20:04 JSTGNU social JP管理人GNU social JP管理人
  1. develop@domainのようなアドレスで共有
  2. develop@, ml@ で用途別
  3. contact@ で一般公開用で共有
開発用のメールなので、1がいいですかね。仮に漏洩しても開発関係経由というのがわかるので。

1がいいと思う。

category

目的に応じて使い分けたほうがよさそう。

メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録

メールアドレス流出時の被害防止

不審なメールの検知

必要な数

  • 銀行・証券会社
  • 知り合い
  • ショッピングサイト

その他

  • Webサイトなどの公開用
  • 本名でのやり取り
  • ニックネーム
  • 金銭のやり取りのないサービス登録
  • 金銭のやり取りのあるサービス登録
  • 登録にメールアドレスが必要だけど,そんなに使っていないメール

メールアドレスの種類

  • フリーメール
  • プロバイダーメール
  • 独自ドメイン

メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト

  • サービス登録用
  • メルマガ購読用(捨てアド)
  • メインアドレス

メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間

メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間

これらを考えてどういう名前で何個用意するかを考える。

とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。

Webサイト公開用にcontact

  • main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
  • contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
  • service: 基本的に受信専用,たまに返信。Webサービス登録用。
  • recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
  • job: 個人事業、仕事用、不動産は事業なのでこちら。
  • money: 金融機関登録用。銀行、証券会社、クレジットカード会社、決済会社・サービス。
  • shop/store: ショッピングサイト、個人間売買サイト。
  • ユーザー名: メールアドレスの@以前はユーザー名とみなされることがあるので、ユーザー名のアドレスも用意しておくとよさそうだ。


こちらから送信するときのメールアドレス。

Webサービスに登録するときどうするか。不動産屋さんとか人に教えるときはどうするか。アフィリエイトとかドメインとか実名が求められるときはどうするか。

gmailの+を考える。gmailでは+や.をつけると無限にアドレスをつけられる。ただし,受信は+のないメール。

ただし,gmailの+は使えないときがある。@以前の部分をユーザー名とみなして,+を無効な文字とみなすサービスがある模様。

ネットではがきが印刷~郵送できるポスコミ【1枚から注文OK】

https://www.tomtop.com/もだめ。

今まで使ってきたメールとはどうやりくりするか。

Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。

他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。

最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。

このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。

Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。

Mozilla Thunderbird

プロファイルの統合

ImportExportToolsでデータ移行するというのが手堅い。一括操作を念頭に置いた機能になっている。数が少ないならば、emlファイルをドラッグドロップで取り込むこともできる。