min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

高知の移住CMと100分de名著「資本論」

高知県のCMが話題となっているようだ。

f:id:min117:20210117120236j:plain

これは田舎と都会のギャップを表現しただけのものではないと思う。

www.youtube.com

他人が勝手に家に入ってくるのが嫌だ、という都会人。

全てのものを「商品」にしてしまう資本主義に慣らされてしまった人間の末路だ。

 

それは、この本を読めばわかる。

NHKテキスト 100分de名著「カール・マルクス 資本論

f:id:min117:20210117120337j:plain

斎藤幸平(「人新生の資本論」の著者)が書いている。

 

そもそもなぜ田舎暮らしをしようと思ったのか?

f:id:min117:20210117121701p:plain

都会にいて、何に渇き、何に飽き飽きしていたのか。なぜ毎日こうも疲れているのか、自分で選んだことではあるけれど、なぜこうも満たされないのか。

 

それは「人間らしい生活」から外れた(外された)ことによる焦燥だ。

そこから回復を望む根源的な欲求。それが田舎暮らしを決意させた理由だろうと思う。

 

この、人間らしい生活から外されることを「疎外」という

 

都会の人間は、資本主義の刃の鋒(きっさき)に晒されて、疎外の真っ只中に、それに慣らされて生活している。だから疲れる。

 

人間が働くということ、「働いて満たされる」ことの根底には「構想と実行」があるという。

f:id:min117:20210117121204p:plain

自分で考え構想し(精神的労働)、それを現実に実行して形にしていく(肉体的労働)。その全過程を通じて、人間は仕事(労働)に達成の喜びを感じられる。

 

しかし、生産性だけを追求する資本主義(の本質)は、働く人間から構想を奪ってしまうという。構想と実行を分離する構想するのは一部の限られた人間・組織・資本(を持つ者)だけで、あとの人間は実行だけをひたすらさせられる。

 

都会ではとくに、それを実感させられるのではないか。端的なのが非正規雇用非正規社員として、切り出された仕事の一部だけを繰り返しさせられる。そこに労働の喜びはない。しかし、カネ儲けと効率だけを重視した現社会において、それは止まらないどころか拡大していく。

www.nippon.com

 

こう書くと

 

「わたしは仕事のしかたは自分で決められるし、誰かに操られてなんかいない」

とか

「いや俺自営業だから。自分で考えなきゃ。やっていけないって」

とか

「それってドカタとか工場労働の非正規だけだよね」

とか。

聞こえてきそうだ。

 

しかしそれは、目先の現実しか見えていない。

 

仕事のしかたを自分で決められるはずのサラリーマンや、個人で回している自営業が「田舎暮らししたいなぁ」という虚しさを感じずに居られるというのだろうか。もしそうなら、これほど田舎暮らしが話題になるはずもない。

 

なぜ皆こうも「渇く」のか。その根本に資本主義による「構想と実行の分離」がある。自分で判断しているようにみえて結局、「カネ儲け」の歯車の一つを回して終わってしまっている。

 

カネ儲けが至上命題になっていて

「カネが無ければ、働け」

「働かないほうが悪い」

生活保護は悪」

などという状況を、皆が当たり前と思うくらい(に資本主義の洗脳が)進んでしまっているのが現実だ。

 

実際は、皆が共同で使えるはずの富(コモン)を資本に吸われて失い、皆が貧しくなっているというのに。

 

仕事の仕方を自分で決められるから自由だ、という勘違いについてもこの本に指摘がある。

f:id:min117:20210117121344p:plain

働くということ=労働の処分について労働者は自由だが、資本主義に飲まれた働き方をした(労働力を処分した)瞬間に、労働の処分権は100%失うのだと。

 

しかし「自由に選んだ」という自負が足枷になって、その現実に気づけない。

f:id:min117:20210117132238p:plain

資本主義の恐ろしいところだ。

 

これが、田舎だとどうか。そこには「カネ儲け」「ゼニ」だけではない豊かさがある。田舎に帰ると、親戚がいて、どこの誰それがどこで働いているとか情報が入って、収穫期には互いに手伝う。お礼は別の機会に別の収穫でする。「生活費(ゼニカネ)のためは働かなくても」ある程度食べていける(生きていける)という下地が、田舎にはある。実はそういった共有・共同の豊かさこそが本当の「豊かなのだとこの本は言っている。

f:id:min117:20210117121701p:plain

目に見えない、数字にはならない、カネではないところで「繋がっている」。皆が共有で使える水や、空気や、食料がある。

 

それは「構想と実行」が統一した働きができるような共同体が、田舎にはまだあるからだ。それを感じられずに生きていた都会の人間が、突然それを目にしたら、そりゃ宇宙人にも見えるだろう。

 

構想と実行の分離を防止するには「共同」による仕組みを作るしかない。

 

都会にいて、マンションの隣は何をする人ぞ、という生活からは想像もつかないだろうが、しかしそれでも、「共同で」の豊かさを持つための試みは(その視点が皆に備われば)できるはずだ。

 

構想と実行の分離を防止し、皆の共有の財産である知やモノ(コモン)誰でもアクセスできるようにする仕組みが、かつてはあった。

 

f:id:min117:20210117121219p:plain

18世紀、ギルドやツンフトは、その組織におけるルールによって行き過ぎた儲けを禁止し、共有の「富」(知識や技術や土地や材料)を誰かが独占することがないように規制を引いていた。

 

しかし、それも資本主義に負けた。作業工程を細分化して、技術者から考える工程を奪い作業だけをさせるようになると、ギルドやツンフトも解体されてしまった。

f:id:min117:20210117121235p:plain

資本主義では、共有の富であったはずの「知(構想)」「場所」を一部の人間(というか資本というか組織が)独占(囲い込み)してしまい、ハジキ出された人間には作業だけをさせるようになるわけだ。

ハジキ出された大多数は、働かなければ生きていけない(共有で使える場所は一部の者に独占=囲い込み されてしまって使えない)から、働かざるを得ない。

f:id:min117:20210117121328p:plain

儲けの視点では最適だろうが、それによって失われているもの(働きがいや人間らしさ)の損失は遥かに大きい。

そして、こうした話は「100年以上前の工場労働」に限った話なんかではない。

 

本来は「皆の共有財産」「誰でもアクセスできるコモン」であった知識やモノ一部の人間や組織が囲い込んで、人口的にでも希少性を作り出し、それを手に入れるためには「作業人間」として働かざるを得ない状況にする。その資本主義の本質は、100年前も今も全く変わっていない(むしろ拡大している)からだ。

f:id:min117:20210117121307p:plain

 

そうやって、人々の「共有」の豊かさを破壊し、カネ儲けだけが是として膨れ上がる資本主義を、マルクスヒンドゥー教の「ジャガンナート」に例えた。

f:id:min117:20210117121250p:plain

拡大した資本主義がもたらすのは(共有の破壊の当然の帰結として)大破綻、恐慌である。

 

直近で最大なのはリーマンショックだろう。この本を読んでから映画「マネー・ショート」(2015年)を見ると、資本主義の理不尽さがよくわかる。

 

youtu.be

 

今、コロナで皆が苦しい。しかし、なぜここまで救いが無いのか。皆が苦しいのか。

 

かつて、リーマンショックが起きる前は、銀行預金の利率は5%だった。100万円預ければ年間で5万円の利息がついた。5,000万円あれば250万円ついた。それは、共有の皆が労働で作り出した富の、民への還元だったのだ。その余裕があれば、これほどの疫病であっても、耐えられる人ももっといたかもしれない。

 

それが破壊されたのは、「ジャガンナート」のごとく狂って膨れたバブル、サブプライムローンの破綻により、そのツケを払わされたことによる。

 

資本主義の暴走(富を貪る)のツケは結局、その富を生み出す源泉(労働)である労働者に返ってしまった。源泉が死ぬのだからこれ以上富は増えない。資本主義が自分の足を食うタコに例えられる(絶対に続かない)とされるのはこのためだ。

 

 

 

 

 

富士通 LIFEBOOK AH77/G FMVA77GRKS ハードディスク(700GB)からSSD(500GB)へ換装 → いちおう成功するも痛い目を見る

2012年製の富士通 LIFEBOOK AH77。遅くて使いものにならないとの相談。

f:id:min117:20210104213311j:plain

当時はHDD+Win7だったものを、OSだけWin10 Homeに上げてしまっている。

f:id:min117:20210104213346p:plain

Win10はSSD前提(たぶん)だからか、HDDじゃ起動すらままならない遅さ。SSDに換装するしかない。

 

買うのはこれ。

f:id:min117:20210104212838p:plain

 

手順はネットにたくさんあるが、今回は700GBのハードディスクを、より容量の小さい500GBのSSDに移すというところにテクニックが要る。

 

結論だけ言っておくと、以下の手順3で死にかけた

 

  

 

まず、移行前(700GBのHDD)のパーティション構成としては

 ① ブート領域:20GB

 ② ゴミ領域?:200MB

 ③ Cドライブ:339GB うち80GB使用

 ④ Dドライブ:339GB うち6GB使用

といった感じ。

つまり、HDD全体としては700GBもあるけれど、実質使用しているのは86GBに過ぎないのだから、これを新たに買ったSSD500GB)にOSごと移したというわけだ。

 

<進め方>

手順1. HDDデータのうち①②③だけをイメージバックアップする(AOMEI Backupperなるソフトを使う)

手順2. SSDにイメージバックアップを書き込む

手順3. OSのブート領域の修復

 

<構成>

f:id:min117:20210117102012j:plain

作業用Win10にAOMEI Backupperをインストールする。

コピー元HDDのデータをイメージバックアップして、一時退避用1TBのHDDに逃がす

コピー先SSDにそれを書き込む。

 

ちなみに作業用のWin10はこれ。安くて良い買い物だった。

min117.hatenablog.com

 

<記録>

ここからは実際にやったことの記録。

 

まずはイメージバックアップを取得。ネット漁ったら「AOMEI Backupper」が良さそうな気がした。中国製のソフトって(日本語が拙いところはあるが)技術的には信頼している。

forest.watch.impress.co.jp

www.aomei.jp

f:id:min117:20210115005600p:plain

f:id:min117:20210115005652p:plain

 

f:id:min117:20210115005737p:plain

 

Standard版で問題なし。

f:id:min117:20210115005755p:plain

f:id:min117:20210115005825p:plain

f:id:min117:20210115005839p:plain

インストール完了。

 

「新規バックアップ」

f:id:min117:20210115011401p:plain

 

パーティションバックアップ」 

f:id:min117:20210115012007p:plain

※ もしかしてここで「システムバックアップ」を選べば冒頭に述べたような死にかけのトラブルは無かったのかも?しれない。 

 

パーティションを追加」

 

f:id:min117:20210115011835p:plain 

 

 

Shiftを押しながら、バックアップしたいパーティションだけを指定できる。これ素晴らしい。

f:id:min117:20210115011900p:plain

繰り返しになるが、移行前(700GBのHDD)の構成はこうなっている。

 ① ブート領域:20GB

 ② ゴミ領域?:200MB

 ③ Cドライブ:339GB うち80GB使用 (Win10 Home)

 ④ Dドライブ:339GB うち6GB使用

これのうち①②③だけを指定できたことになる。

 

コピーしたファイル(イメージバックアップファイル)をどこに置くかを指定する。

f:id:min117:20210115012223p:plain

退避用の1TBのハードディスクを指定した。

f:id:min117:20210115012246p:plain

 

バックアップ開始。

f:id:min117:20210115012312p:plain

f:id:min117:20210115012442p:plain

 

今回使ったケーブルはUSB3.0(だったと思う)。

f:id:min117:20210117104252p:plain

バックアップには約1時間かかった。

 

完了。

f:id:min117:20210115020302p:plain

バックアップファイルの容量は59GB。これなら移行先のSSD(500GB)に収まる。

f:id:min117:20210115020231p:plain

 

作業用PCの電源をいったん切って

f:id:min117:20210115020332p:plain

 

リーダーからHDDを外し、SSDを装着。

f:id:min117:20210115020535j:plain f:id:min117:20210115020539j:plain

 

今度は「復元」メニューに入る。 

f:id:min117:20210115020748p:plain

 

書き込むデータ(イメージバックアップ)を選ぶ。

f:id:min117:20210115020809p:plain

退避用の1TBのハードディスクにある59GBのファイルを指定する。

f:id:min117:20210115020828p:plain

 

どのパーティションを復元するか選ばされるが、ここで複数指定はできないので、一つ一つ復元していく。

f:id:min117:20210115020907p:plain

ちなみに、退避用HDDにバックアップしたイメージファイルが59GBしかないのに、それを復元すると「20GB、200MB、339GB(合計359GB)」にもなるのはなぜ?と思うかもしれないが、それは圧縮しているから

AOMEIのようなイメージバックアップソフトは、パーティションを(独自のフォーマットにより)1つのファイル(59GB)に圧縮して保存している。こういうソフトのキモと言える。

 

コピー先には500GBのSSD(実際は495.76GB)を選択する。

f:id:min117:20210115021016p:plain

※この記事を書いてる今になって気づいたが、コピー元HDD(画像中のディスク0、223.57GB)がGPTになっているのに、コピー先SSD(画像中のディスク1、495.76GB)MBRじゃないか!

これじゃコピーしてもSSDからWindowsが起動できるはずがない。あらかじめSSD(の起動領域)をGPTにしておくとうまくいったのかも。

 

 

 

 

 

コピー確認画面が出るので「開始」

f:id:min117:20210115021053p:plain

の前に、左下の「パーティションを編集」も見ておく。

 

パーティション編集しないので「キャンセル」。

f:id:min117:20210115021130p:plain

いよいよ「開始」。

 

SSDだけに書き込みは速い。

f:id:min117:20210115021242p:plain

20GBは10分くらい?で書き込み完了した。

 

次は200MB部分を同じ手順で書き込む。

f:id:min117:20210115063211p:plain

f:id:min117:20210115063133p:plain

f:id:min117:20210115063302p:plain

f:id:min117:20210115063352p:plain

3秒で完了。


最後に一番大きい領域(339.22GB、Win10 Homeが入っている)を書き込む。

f:id:min117:20210115063449p:plain

コピー先(ターゲットパーティション)としてSSD(ディスク1)の空き領域445.56GBを指定する。

f:id:min117:20210115063542p:plain

コピー開始。

f:id:min117:20210115063628p:plain

コピー完了!

f:id:min117:20210115073319p:plain


コピー後のSSDをセットして

f:id:min117:20210104213346p:plain

 

起動!…しない。失敗。

f:id:min117:20210115234233j:plain

Windows Boot Managerを押してもこの画面に戻ってしまう。Windowsロゴが出ない。

 

繰り返しになるが、移行前(700GBのHDD)の構成はこうなっていた。

 ① ブート領域:20GB

 ② ゴミ領域?:200MB

 ③ Cドライブ:339GB うち80GB使用(Win10 Home)

 ④ Dドライブ:339GB うち6GB使用

これのうち①②③だけをSSDにコピーしたのに、そのSSDからは起動できていないことになる。

 

おそらくだけど①までは読めている。つまり

電源投入→BIOS→①でブート領域を読む まではOKなのでこの画面が出た。

f:id:min117:20210117111255p:plain

しかし画像にあるWindows Boot Manager③の領域(Windows Homeが入っている)を読めていないというか、③領域にたどり付けていない

 

このあと、別に用意したWindows10 Proの修復ディスクから起動して色々とコマンドを試したらブート領域を壊してしまったようで、画像にあるWindows Boot Managerすら起動しなくなってしまった。

焦ってSSDを取り外し、元々入っていたHDDを付け直して起動したら、そのHDDからも起動エラーになるという地獄を見た。

人様から「HDDからSSDへのスピードアップ」をお願いされたPCが、起動すらできない「故障」になって返るのではシャレにならない。

 

結論としては、修復ディスクから起動してWindows Proの追加インストールしたところ、Boot領域が復活して起動できるようになった。

つまり

SSDを装着

Windows10 Proの修復ディスクから起動する

・Windows10 Proの「インストール」に進む

・「ディスク内に既存のWindows10 Home」を修復しますか?それとも「新たにWindows10 Pro」を追加インストールしますか?

追加インストールを選択

したところ、Bootメニューが復活した。

 

SSD内部はこうなった。

 ① ブート領域:20GB

 ② ゴミ領域?:200MB

 ③ Cドライブ:339GB(Win10 Home)

 ④ Dドライブ:339GB(Win10 Pro)

 

パソコン起動時にWin10 HomeProを選べるようになったので、Homeを選べば、今回の作業前に使っていた(HDDにあった)のと同じ環境を使える。SSDなので速度も爆速だ。

 

ちなみにProはインストールしたけど、Windowsのライセンス認証はしていない。起動しても「ライセンス認証されていません」が出てしまう。けど、こっちは使うことがないので問題なし。

Windowsシステムプロパティから、デフォルトの起動OSを10に指定し、起動の待ち時間を1秒に指定してやったので、使う人は何も意識せずにHomeを使えるだろう。

 

一応目的は達成したけど、他人のWindows10を起動できなくしてしまうという、これまでで最大の危機を味わった。気楽に修理を請け負うもんじゃないな。もう少し修行がいる。

・GPTとMBRの違い

・bootrecがどの領域に書き込んでいるのか?BIOSのどこかを書き換えてしまっている?あくまで今挿しているHDD(やSSD)のbootに書き込んでいるだけだと思っていたが?

・bootrec /fixmbrは何をしている?(GPTにこれやったら何起きる?)

・bootrec /fixbootは何をしている?

・bootrec /scanos はどこを読んでいる?

・Diskpartのactiveの意味は?MBR環境にDiskpartで操作していいのか?

 

freesoft.tvbok.com

freesoft.tvbok.com

 

<作業メモ>

結論

Windows10 bcdまわりの起動トラブルは、空きパーティションにWin10再インストールしてWindowsに起動領域を直させるのが一番確実 

 

memo

bootrec /fixmbr

bootrec /fixboot ここでエラーになり

bootrec /scanos で最初はSSDにあるWindowsがEドライブに見えていたのに

このあと

Diskpart で Eをactiveに設定してからおかしくなった。

 

bootrec /fixbootが「アクセス拒否」でエラーになり

bootrec /scanos にもWindowsが見えなくなってしまい

再起動したら WinBootManager?が、署名なしのようなエラーになり、打つ手なし。

 

さらに恐ろしかったのは、SSDを外し、当初のHDDを挿しても起動エラーになってしまったこと。

bootrec や DiskpartはあくまでSSDの中のbcd領域?をいじるだけで、物理的に別のHDDには関係ないはずなのに、HDDを挿したらWinBootManagerがエラーを吐きやがる。何が起きた?

 

修理依頼されたPCなのに、SSDからも起動せず、既存のHDDからも起動できないとなると責任問題だ。大変。

 

ここで、SSD内部は

第1パーティション HDDからクローンした起動領域

第2パーティション HDDからクローンしたゴミ?領域

第3パーティション HDDからクローンしたWin10Homeが入っている

という状況。

 

ここで、Win10ProのインストールディスクからCD起動して

第4パーティション の空き領域にWin10Proを追加インストールでつっこんだところ、boot領域が修復されて?か、Win10HomeもProも両方見えるようになり、解決した


cmd> msinfo32


 

一番参考になるリンク

freesoft.tvbok.com

freesoft.tvbok.com

 

その他参考にしたリンク

www.ubackup.com

 

www.partitionwizard.jp 

katata.info

将棋GIF 飛車をいぢめる

f:id:min117:20210105000907p:plain

将棋は昔から好きで。当然のごとく将棋ウォーズにハマっている。

 

昨年2020年末には有料会員(対戦回数に制限のない)にも入会してしまった。その後、何台もあるスマホそれぞれに捨てアカウント(対戦3回まで無料)を作れば3の倍数回は楽しめることがわかり退会したが。

 

それはさておき、気持ちよく勝った棋譜はいつもハードコピーを撮ってしまう(とくに「勝利」の画面は必ず)。せっかくとったハードコピーなんだから、繋げればアニメーションGIFにできるじゃんと思い立ち。さっそくやってみた。

 

でけた。

f:id:min117:20210105000238g:plain

今回は2筋の相手飛車を角と銀で執拗にいぢめてみた。8筋に逃げたところを角で仕留め、即2九飛車して玉を詰むまで。2級だと遊びにもならなくなってきたな。

 

ちなLinuxだと convert コマンドで一瞬でGIFアニメが作れる。

f:id:min117:20210105000407p:plain

めっちゃ便利。しばらく棋譜アニメにハマりそう。

min117.hatenablog.com

 

将棋最高。Linux最高。

 

 

 

Windows10 SSDの寿命を3倍にする「SSD最適化設定」を試す(ハイバネーション無効化、ページファイルの無効化、インデックス機能のOff)

f:id:min117:20210104225226p:plain

 

bitFlyer口座開設(ビットコイン1,000円もらえる)URL

 

昨年2020年に買ったものの中でも、Windows10(SSD240GB)が大活躍している。

min117.hatenablog.com

ただいかんせんSSDなので寿命が心配だ。

 

気になる記事。SSDの寿命に最適化する、とある。

itwebkatuyou.com

Windows7や8向けの記事ではあるけど、Win10にも適用できる(と私見だけど思う)内容がいくつかあった。

 

全てやっておく。環境によっては3倍以上SSDの寿命が長くなるようだ。

 

まずはハイバネーションの無効化

f:id:min117:20210104215423p:plain

そりゃそうだ。ハイバネード(いわゆるスリープ状態)になるたびOSイメージをディスクに書き出しているわけだから、こんなことしてたんじゃディスクの寿命が縮むに決まっている。

 

メモリは8GB以上あるし、ハイバネーションなんて無効化してよかろう。

 

コマンドプロンプトを管理者として実行し

f:id:min117:20210104215735p:plain

 

powercfg /hibernate off

f:id:min117:20210104215856p:plain

 これだけ。ハイバネーションが無効になった

 

次はページングファイルの無効化。

f:id:min117:20210104215457p:plain

 

ページングファイル結局、メモリから溢れたデータをディスクに書き出す処理なわけで、SSDへの書き込み回数が多い。しかしメモリは8GB以上あるし(重い処理もしないから)溢れる心配もない。無効にする。

 

コマンドプロンプトを管理者実行して、メモリ容量を確認。

systeminfo | find "メモリ" 

f:id:min117:20210104220142p:plain]

うむ。確かに物理メモリが8GB以上ある。

 

コントロールパネルを開く。 

コマンドプロンプトから「ncpa.cpl

で、開いた画面からコントロールパネルに行くのが実は一番早い。

f:id:min117:20210104220842p:plain

システムとセキュリティを開いて 

 

セキュリティとメンテナンスに入り

f:id:min117:20210104220949p:plain

システムの詳細設定をクリック。

f:id:min117:20210104221057p:plain

 

ページングファイルなしにする。

f:id:min117:20210104221400p:plain

 

はい

f:id:min117:20210104222913p:plain

 

OK

f:id:min117:20210104222849p:plain

あとはパソコンを再起動すると、ページングファイル(C:¥pagefile.sys)が作られなくなる。
 

最後はインデックス機能の無効化

f:id:min117:20210104215527p:plain

これはキク。インデクシングなんてしなくていい。ファイル検索を速くする方法なんていくらでもある(一番は結局どのフォルダに何が入っているか自分が把握して管理すること)。

 

やってみる。Cドライブを右クリック→プロパティ

f:id:min117:20210104223006p:plain

 

一番下のチェックボックスを外し「適用」。

f:id:min117:20210104223122p:plain

 

「変更を…サブフォルダー及びファイルに適用する」

f:id:min117:20210104223149p:plain

 

(エラーは)すべて無視。

f:id:min117:20210104223221p:plain

 

ここでかなり時間がかかる。

f:id:min117:20210104223234p:plain

終わったらPCを再起動。これで無駄なインデックスが作られなくなるから、ディスク負荷が大幅に下がる。

 

サーバ用途での運用がメインだから、別にHDDでもいいっちゃいいけど、Excelも使うからパキパキ動いて欲しいし、それにも増して、macOSからリモートデスクトップParallels使用)で

f:id:min117:20210104233816p:plain

接続した時の異様な速さをいったん体感すると、SSD最高。

もうHDDに戻る気がしない。

 

ちなみに年始の初売りセールでSSDSamsung)がお買い得になってたのでポチってしまった。

f:id:min117:20210104212838p:plain

250GBが4,990円なので、500GBで5,990円は安いおえ。明日1/5(火)23:59まではこの価格らしい。ぽち。

 

 

 

 

 

RaspberryPi3 起動時にfstabマウントしたフォルダが読み込み専用になってしまう → fstabに権限設定uidとgidを設定して解決

f:id:min117:20210102232909p:plain


RaspberryPi起動時に /etc/fstab にNAS(ネットワーク上にあるfedoraで共有しているフォルダ)を書いて自動マウントさせている。

 

min117.hatenablog.com

 

Piは2台あって

 

1台目はうまくマウントできている。

f:id:min117:20210102230506p:plain

drwxrwxrwx+ なので、ふだん使うユーザーPiで書き込みができる

 

2台目がうまくいかない。

f:id:min117:20210102230504p:plain

drwxr-xr-x+ なので、ふだん使うユーザーPiで書き込みができない

 

例えばこんなことになっちゃう。

$ cd 共有ドライブ(今回はPT3というフォルダ)

$ ifconfig | tee -a ip_pi32.txt

エラー tee: ip_pi32.txt: 許可がありません

f:id:min117:20210102233218p:plain

おかしいなぁ。1台目のfstabをそのまま2台目で使用したんだけど、何が違うんだ。

 

ググったら(海外にも同じく困っている人がいると見えて)解決法が分かった。

f:id:min117:20210102231332p:plain

 

fstab に 普段使いのユーザー(pi)のuidとgidを書いてやれば直るらしい。

まずはユーザー(pi)のuidとgidを調べる。コマンド「whoami」「id」を使う。

$ whoami

$ id

f:id:min117:20210102231542p:plain

uidが1000、gidも1000と分かった。

 

あとはこれをfstabに書いてやればいい。

$ sudo vim /etc/fstab

f:id:min117:20210102231940p:plain

 

書いたらpiを再起動。

$ sudo reboot

f:id:min117:20210102232114p:plain

 

フォルダの所有者がpiに変わった(再起動前はrootの所有だった)

f:id:min117:20210102232548p:plain

ので

 

書き込み可能になった。

f:id:min117:20210102233435p:plain

権限設定って結構手間取るけど、今回はサクッと解決できてよかった。成果として fstabでuid、gid設定できる ことは覚えておく。

 

min117.hatenablog.com

 

参照

tutorialmore.com

 

 

 

 

 

PHP 再帰関数その5(完成)

f:id:min117:20210102110716p:plain

 

PHP再帰関数によるフォルダ読み込み実装の続き。

min117.hatenablog.com

さらに改良。

 

今いるgetcwd()フォルダにあるオブジェクトを舐めて、フォルダだったらその中に入る(1階層降りる)+そこにあるオブジェクトをまた表示するためのボタンを再帰関数で実装した。

 

こういうフォルダだと

f:id:min117:20210102102112p:plain


こんな動きになる。

f:id:min117:20210102103242g:plain

これで、どんなに階層が深くてもフォルダを潜って辿れるシンプルなPHPができた。いろいろと活用できそう。

 

ソースはこれ。
f:id:min117:20210102110310p:plain

11行目 読み込む階層上限($kaisou_limit)は2とした。今いるフォルダの直下にあるディレクトリだけ取れればいいから。

19行目 $kaisou_limitはグローバル変数として宣言する。再帰で呼ばれた全ての関数インスタンスから参照されるから。

23〜56行目 読み込んだオブジェクトがファイルだった場合の処理

44〜46行目 ファイルの存在するPATHから文字列を切り出して、http://のリンクの一部として使う。explode()関数は、PATHをバラバラに切り離して配列に入れ、その一部だけを指定して利用できる。

57行目 ここに入るときは$pathには(ファイルじゃなくて)フォルダが入っていることが確定している。

 

f:id:min117:20210102110157p:plain

f:id:min117:20210102103620p:plain

フォルダの読み込みボタン実装が難しかった。

 

こんな感じで、フォルダの読み込みボタンが出る。

f:id:min117:20210102104527p:plain

 

86〜94行目でボタンを作って、submitでこのPHPファイルを読み込むと

f:id:min117:20210102104934p:plain

DIR_PATHがセットされるので

 

97行目の(if文の)処理に入るから

f:id:min117:20210102105135p:plain

 

そのif文中で実行してる再起関数つまりgetDirList()が発火して

f:id:min117:20210102105014p:plain

さらに下の階層を読みにいく。その際に、今いる階層を引数$kaisou_nowで渡す。

 

そうすると、再帰で呼ばれたgetDirList()関数インスタンスの中では、渡された階層に+1して表示してくれる。

f:id:min117:20210102105425p:plain

+1して、$kaisou_limitに達したら、何もしないで戻る。

 

コピペ+保存用

<?php

 

// nikkei XTECK

// 54. 再帰関数を使ってみよう

// https://xtech.nikkei.com/it/article/COLUMN/20070827/280408/

 

// 引数$path にはディレクトリorファイルの絶対パスを指定する。

 

// $saiki = 0;

$kaisou_now = 0;

$kaisou_limit = 2;

 

function getDirList($path ,$kaisou_now) {

    /// 階層を引数で受け取ると、親フォルダに戻った時に正しく階層-1される

    /// global $kaisou;しちゃうと、親フォルダに戻った時に階層+1されバグる

    // global $saiki;

    // global $kaisou_now;

    // $total_size = 0;

    global $kaisou_limit;

    print '<br>';

 

    //指定したのがファイルだった場合

    if (is_file($path)) {

        // print '再帰:' . $saiki . '回目';

        // print '<br>';

        print '<font color="blue">ファイル</font>パス:<br>' . "$path";

        print '<br>';

 

        print '階層:' . $kaisou_now;

        print '<br>';

 

        //URLリンク表示

        $myFILE_PATH = $path;

        print '<br>================<br>';

        print $myFILE_PATH;

        print '<br>================<br>';

        // getDirList($path . '/' . $obj, $kaisou_now);

        // getDirList($myRUN1 . '/' . $obj, $kaisou_now);

 

        // explode()文字列分割 第三因数オプションにてlimit値(分割回数)を指定できる

        // /media/6TB/mp3z を スラッシュ区切りで3つに分割して配列に格納し

        //        6TB/mp3z ← その配列の2つ目(_STR[2])を表示する

        // localパス

        $myFILE_PATH_STR = explode("/", $myFILE_PATH ,3);

        print $myFILE_PATH_STR[2];

        print '<br>';

        // URL

 

        $myFILE_PATH_URL = 'http://192.168.3.11:8080/' . "$myFILE_PATH_STR[2]" ;

        print $myFILE_PATH_URL;

        print '<br>';

        print '<a href="' . "$myFILE_PATH_URL" . '" target="_blank">' . basename($myFILE_PATH) . '</a>';

        print '<br>';

 

 

        // return filesize($path);

    } elseif (is_dir($path)) {

        // カレントディレクトリ(.)or

        // 上位階層ディレクトリ(..)の場合はここで終了

        $basename = basename($path);

        if ($basename == '.' || $basename == '..') {

            return 0;

        }

 

        // if ($kaisou_now == 3) {

        //     return 1;

        // }

 

        // ファイルでもなく、カレント(.)でもなく、親(..)でもない

        // つまりディレクトリだったら、フォルダpathとして表示

        print '<font color="red">フォルダ</font>パス:<br>' . "$path";

        print '<br>';

 

        // 階層を表示

        $kaisou_now++;

        print '階層:' . $kaisou_now;

        print '<br>';

        print '階層limit:' . $kaisou_limit;

        print '<br>';

 

 

        ///// ボタンのクリックでphp関数を実行する

        // https://tutorialmore.com/questions-1286453.htm

        // print '<input type="button" name="someAction" value="Go" /><br>';

        // print '<form method="post">';

        print '<form method="GET">';

            print '<input type="hidden" name="DIR_PATH" id="ID_DIR_PATH" value="' . "$path" . '" /></br>';

            // print '<input type="submit" name="RUNNN2" id="ID_RUN2" value="RUN2" /></br>';

            print '<input type="submit" name="RUNNN2" id="ID_RUN2" value="' . basename($path) . '" /></br>';

        print '</form>';

 

        if($kaisou_now >= $kaisou_limit) {

            return 0;

        }

 

        // if(array_key_exists('RUNNN2',$_POST)) {

        if(array_key_exists('DIR_PATH',$_GET)) {

            $myDIR_PATH = $_GET['DIR_PATH'];

            print '<br>================<br>';

            print $myDIR_PATH;

            print '<br>================<br>';

            // getDirList($path . '/' . $obj, $kaisou_now);

            // getDirList($myRUN1 . '/' . $obj, $kaisou_now);

 

            // explode()文字列分割 第三因数オプションにてlimit値(分割回数)を指定できる

            // /media/6TB/mp3z を スラッシュ区切りで3つに分割して配列に格納し

            //        6TB/mp3z ← その配列の2つ目(_STR[2])を表示する

            // localパス

            $myDIR_PATH_STR = explode("/", $myDIR_PATH ,3);

            print $myDIR_PATH_STR[2];

            print '<br>';

            // URL

            $myDIR_PATH_URL = 'http://192.168.3.11:8080/' . "$myDIR_PATH_STR[2]" ;

            print $myDIR_PATH_URL;

            print '<br>';

            print '<a href="' . "$myDIR_PATH_URL" . '">' . basename($myDIR_PATH) . '</a>';

            print '<br>';

 

            // ディレクトリ内にあるオブジェクト(ファイルまたはディレクトリ)の一覧を入手

            // $obj_list = scandir($path);

            $obj_list = scandir($myDIR_PATH);

 

            foreach ($obj_list as $obj) {

                ///// ボタンのクリックでphp関数を実行する 

                // print '<input type="button" name="' . basename($obj) . '" id="id_' . basename($obj) . '" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '" /><br>';

 

                ///// ↓ これだと、onclick()と書いても、クリックの有無に関係なくgetDirListが読まれてしまう

                // サーバがパースしちゃうから

                // print '<input type="button" name="test" id="test" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '"/><br>';

                // if( is_dir($obj)) {           

                // }

 

                // getDirList($path . '/' . $obj, $kaisou_now);

                getDirList($myDIR_PATH . '/' . $obj, $kaisou_now);

 

                // print "$obj"; 

 

 

                // ディレクトリ内のオブジェクトを引数にして、自分自身を呼び出す再帰

                // getDirList($path . '/' . $obj);

                // $total_size += getDirList($path . '/' . $obj);

                // $objがディレクトリだったら

                // また自分自身を呼び出す(再帰)して…を繰り返して

                // 最深部の階層(ファイルのみが存在する階層)まで行く

            }

            // return $total_size;

            // print '階層ぅ:' . "$kaisou_now" . '<br>';

        }

 

    } else {

        return 0;

    }

}

 

// カレントフォルダの確認

print '------------------------<br>';

print getcwd() . '<br>';

print '階層:' . $kaisou_now;

print '<br>';

print '------------------------<br>';

 

//関数実行

// print getDirList('/media/WD30EZRX/PT3/test_pdf2jpg');

// print getDirList("getcwd()");

// print getDirList("/media/6TB/mp3z");

print getDirList(getcwd(), 0);

 

 

 

?>

my_recursive07.php                                                     169,0-1       末尾

正月を利用して良いものつくれた。基礎的だけど根本的な部品って、こういう時間あるときしか作れない。かなり使い回しが効くはず。今年は良い年になりそうだ。

 

 

 

 

PHP 再帰関数その4

f:id:min117:20210102020211p:plain

 

フォルダ階層の再帰関数による読み込み。前回の続き。

min117.hatenablog.com

 

改良して、以下の機能を実装した。

 

読み込んだオブジェクトが

 ファイルの場合は何もしないけど

 フォルダの場合には「Go」ボタンを表示して、押せばさらに下の階層に行けるようにした(というか、そうしたいので、まずはGoボタンだけ表示した)

f:id:min117:20210102004733p:plain

 

現在いる場所(getcwd)の階層($kaisou_now)を関数の引数として受け取るようにした。

f:id:min117:20210102004914p:plain

子フォルダを読み終えて親フォルダに戻る時に階層を1減らすとこの実装が難しいんだけど、子フォルダを読む(再帰する)ときに、今の階層($kaisou_now)を引数で渡せば解決することが分かった。そうすれば、子フォルダに行くときだけ階層が+1されて、戻った時には前の階層数に戻ることができる。

 

読み込む階層の深さ($kaisou_limit)を指定できるようにした。

f:id:min117:20210102004914p:plain

あらかじめ階層の深さ限界($kaisou_limit)を宣言しておいて

$kaisou_nowがそれより深く潜る前にreturn する。

f:id:min117:20210102005719p:plain

$kaisou_limit をユーザーに入力させれば、読み込みたい任意の深さまでのフォルダを辿るようにできる。$kaisou_limitは(再帰された関数インスタンスの)全てから参照されるので、グローバル変数としておく(19行目)。

 

ソース変更による動きの変化はこんな感じ。

f:id:min117:20210102015301g:plain

次回はさらに改良して「Go」ボタン押下でそのフォルダ階層に降りていく処理を実装する。Goボタン(input type="button"のとこ。下のソースの58行目)を押した時に再起関数を呼ぶとこの実装が難しそう。

 

今回のソース全景。

f:id:min117:20210102015706p:plain

f:id:min117:20210102015731p:plain

 

コピペ保存用

<?php

// nikkei XTECK

// 54. 再帰関数を使ってみよう

// https://xtech.nikkei.com/it/article/COLUMN/20070827/280408/

 

// 引数$path にはディレクトリorファイルの絶対パスを指定する。

 

// $saiki = 0;

$kaisou_now = 0;

$kaisou_limit = 2;

 

function getDirList($path ,$kaisou_now) {

    /// 階層を引数で受け取ると、親フォルダに戻った時に正しく階層-1される

    /// global $kaisou;しちゃうと、親フォルダに戻った時に階層+1されバグる

    // global $saiki;

    // global $kaisou_now;

    // $total_size = 0;

    global $kaisou_limit;

    print '<br>';

 

    //指定したのがファイルだった場合はサイズを返して終了

    if (is_file($path)) {

        // print '再帰:' . $saiki . '回目';

        // print '<br>';

        print '<font color="blue">ファイル</font>パス:<br>' . "$path";

        print '<br>';

 

        print '階層:' . $kaisou_now;

        print '<br>';

 

        return filesize($path);

    } elseif (is_dir($path)) {

        // カレントディレクトリ(.)or

        // 上位階層ディレクトリ(..)の場合はここで終了

        $basename = basename($path);

        if ($basename == '.' || $basename == '..') {

            return 0;

        }

 

        // if ($kaisou_now == 3) {

        //     return 1;

        // }

 

        // ファイルでもなく、カレント(.)でもなく、親(..)でもない

        // つまりディレクトリだったら、フォルダpathとして表示

        print '<font color="red">フォルダ</font>パス:<br>' . "$path";

        print '<br>';

 

        // 階層を表示

        $kaisou_now++;

        print '階層:' . $kaisou_now;

        print '<br>';

        print '階層limit:' . $kaisou_limit;

        print '<br>';

 

        print "$obj";

        print '<input type="button" name="someAction" value="Go" /><br>';

 

        if($kaisou_now >= $kaisou_limit) {

            return 0;

        }

        // ディレクトリ内にあるオブジェクト(ファイルまたはディレクトリ)の一覧を入>手。

        $obj_list = scandir($path);

 

        foreach ($obj_list as $obj) {

            ///// ボタンのクリックでphp関数を実行する 

            // https://tutorialmore.com/questions-1286453.htm

            // print '<input type="button" name="' . basename($obj) . '" id="id_' . basename($obj) . '" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '" /><br>';

 

            ///// ↓ これだと、onclick()と書いても、クリックの有無に関係なくgetDirListが読まれてしまう

            // サーバがパースしちゃうから

            // print '<input type="button" name="test" id="test" value="RUN" onclick="' . getDirList($path . '/' . $obj) . '"/><br>';

            // if( is_dir($obj)) {           

            // }

 

            getDirList($path . '/' . $obj, $kaisou_now);

 

            // ディレクトリ内のオブジェクトを引数にして、自分自身を呼び出す再帰

            // getDirList($path . '/' . $obj);

            // $total_size += getDirList($path . '/' . $obj);

            // $objがディレクトリだったら

            // また自分自身を呼び出す(再帰)して…を繰り返して

            // 最深部の階層(ファイルのみが存在する階層)まで行く

        }

        // return $total_size;

        // print '階層ぅ:' . "$kaisou_now" . '<br>';

 

    } else {

        return 0;

    }

}

 

// カレントフォルダの確認

print '------------------------<br>';

print getcwd() . '<br>';

print '階層:' . $kaisou_now;

print '<br>';

print '------------------------<br>';

 

//関数実行

// print getDirList('/media/WD30EZRX/PT3/test_pdf2jpg');

// print getDirList("getcwd()");

// print getDirList("/media/6TB/mp3z");

print getDirList(getcwd(), 0);