[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f24yx8fwi9sx99":3,"$f2fnxuk5hosvie":45},{"sha":4,"committedAt":5,"fetchedAt":6,"source":7,"skill":8},"d545ab58bb89a5f88a08034a056af464abc229bf","2026-09-04T15:40:39.000Z","2026-09-04T15:49:35.573Z","github",{"slug":9,"name":10,"description":11,"tags":12,"author":17,"authorUrl":18,"requires":19,"badges":20,"fileCount":23,"totalBytes":24,"tree":25,"errors":44},"remote-ops","Remote Ops Quoting","The ssh argument-flattening trap that silently runs your command on the wrong machine, the two forms that work, and the base64 hop for anything with nested quotes or SQL.",[13,14,15,16],"ops","ssh","proxmox","shell","Patrity","https:\u002F\u002Fgithub.com\u002FPatrity",[14],[21,22],"skills","claude-md",3,6903,[26,38,41],{"name":21,"path":21,"type":27,"children":28},"dir",[29],{"name":9,"path":30,"type":27,"children":31},"skills\u002Fremote-ops",[32],{"name":33,"path":34,"type":35,"size":36,"kind":37},"SKILL.md","skills\u002Fremote-ops\u002FSKILL.md","file",4091,"text",{"name":39,"path":39,"type":35,"size":40,"kind":37},"CLAUDE.md",384,{"name":42,"path":42,"type":35,"size":43,"kind":37},"README.md",2428,[],{"path":42,"language":46,"size":43,"kind":37,"content":47,"frontmatterRaw":48,"body":49,"data":622},"markdown","---\nname: Remote Ops Quoting\ndescription: The ssh argument-flattening trap that silently runs your command on the wrong machine, the two forms that work, and the base64 hop for anything with nested quotes or SQL.\ntags: [ops, ssh, proxmox, shell]\nauthor: Patrity\nauthorUrl: https:\u002F\u002Fgithub.com\u002FPatrity\nrequires: [ssh]\n---\n\n# Remote Ops Quoting\n\nOne skill about one bug, because that bug produces a confident, detailed, completely wrong report.\n\n## What's inside\n\n| Path | Purpose |\n| --- | --- |\n| `skills\u002Fremote-ops\u002F` | How `ssh` flattens its arguments, the broken vs. correct forms, the base64 hop for nested quotes and SQL, and the `hostname` check. |\n| `CLAUDE.md` | A pointer block to paste into your project's `CLAUDE.md`. |\n\n## The bug\n\n`ssh` joins all of its arguments into a single command string, so your local quoting is gone before\nthe remote shell sees it. A nested `bash -lc` then takes only the **first word** as its script:\n\n```bash\n# ✗ prints a blank line, then the OUTER HOST's hostname\nssh root@\u003Chost> -- pct exec \u003Cctid> -- bash -lc 'echo hi; hostname'\n\n# ✓ prints \"hi\", then the container's hostname\nssh root@\u003Chost> \"pct exec \u003Cctid> -- bash -lc 'echo hi; hostname'\"\n```\n\nBoth exit 0. The broken form either runs everything after a `;` or `&&` on the outer host, or runs\na bare first word with the rest discarded into `$@`. It has already turned a healthy production\ncontainer into a report that the app directory was missing, the service inactive and `docker` not\ninstalled — every one of those true of the host, none of them true of the container.\n\nThe same shape appears anywhere a remote command nests: `ssh … docker exec … sh -c '…'`,\n`ssh … sudo -u app bash -lc '…'`, `ssh … kubectl exec … -- sh -c '…'`.\n\n## The rule worth memorising\n\n**When a remote result surprises you, run `hostname` before believing it.** \"Not found\", \"not\ninstalled\", \"no such directory\" is what a perfectly healthy outer host says when your command never\nreached the container.\n\n## Install\n\n```bash\nunzip remote-ops.zip\nmkdir -p .claude\u002Fskills\ncp -R remote-ops\u002Fskills\u002F. .claude\u002Fskills\u002F\ncat remote-ops\u002FCLAUDE.md >> CLAUDE.md\n```\n\nNo configuration. The examples use `\u003Chost>`, `\u003Cctid>`, `\u003Capp>` and `\u003Ccontainer>` placeholders —\nsubstitute your own, and keep the project's real hosts in a project-local skill rather than here.\n\n## Requirements\n\n- `ssh` on PATH, and `base64` on both ends for the payload form.\n","name: Remote Ops Quoting\ndescription: The ssh argument-flattening trap that silently runs your command on the wrong machine, the two forms that work, and the base64 hop for anything with nested quotes or SQL.\ntags: [ops, ssh, proxmox, shell]\nauthor: Patrity\nauthorUrl: https:\u002F\u002Fgithub.com\u002FPatrity\nrequires: [ssh]",{"type":50,"children":51},"root",[52,59,65,72,156,162,188,374,411,439,445,462,468,552,587,593,616],{"type":53,"tag":54,"props":55,"children":57},"element","h1",{"id":56},"remote-ops-quoting",[58],{"type":37,"value":10},{"type":53,"tag":60,"props":61,"children":62},"p",{},[63],{"type":37,"value":64},"One skill about one bug, because that bug produces a confident, detailed, completely wrong report.",{"type":53,"tag":66,"props":67,"children":69},"h2",{"id":68},"whats-inside",[70],{"type":37,"value":71},"What's inside",{"type":53,"tag":73,"props":74,"children":75},"table",{},[76,95],{"type":53,"tag":77,"props":78,"children":79},"thead",{},[80],{"type":53,"tag":81,"props":82,"children":83},"tr",{},[84,90],{"type":53,"tag":85,"props":86,"children":87},"th",{},[88],{"type":37,"value":89},"Path",{"type":53,"tag":85,"props":91,"children":92},{},[93],{"type":37,"value":94},"Purpose",{"type":53,"tag":96,"props":97,"children":98},"tbody",{},[99,133],{"type":53,"tag":81,"props":100,"children":101},{},[102,113],{"type":53,"tag":103,"props":104,"children":105},"td",{},[106],{"type":53,"tag":107,"props":108,"children":110},"code",{"className":109},[],[111],{"type":37,"value":112},"skills\u002Fremote-ops\u002F",{"type":53,"tag":103,"props":114,"children":115},{},[116,118,123,125,131],{"type":37,"value":117},"How ",{"type":53,"tag":107,"props":119,"children":121},{"className":120},[],[122],{"type":37,"value":14},{"type":37,"value":124}," flattens its arguments, the broken vs. correct forms, the base64 hop for nested quotes and SQL, and the ",{"type":53,"tag":107,"props":126,"children":128},{"className":127},[],[129],{"type":37,"value":130},"hostname",{"type":37,"value":132}," check.",{"type":53,"tag":81,"props":134,"children":135},{},[136,144],{"type":53,"tag":103,"props":137,"children":138},{},[139],{"type":53,"tag":107,"props":140,"children":142},{"className":141},[],[143],{"type":37,"value":39},{"type":53,"tag":103,"props":145,"children":146},{},[147,149,154],{"type":37,"value":148},"A pointer block to paste into your project's ",{"type":53,"tag":107,"props":150,"children":152},{"className":151},[],[153],{"type":37,"value":39},{"type":37,"value":155},".",{"type":53,"tag":66,"props":157,"children":159},{"id":158},"the-bug",[160],{"type":37,"value":161},"The bug",{"type":53,"tag":60,"props":163,"children":164},{},[165,170,172,178,180,186],{"type":53,"tag":107,"props":166,"children":168},{"className":167},[],[169],{"type":37,"value":14},{"type":37,"value":171}," joins all of its arguments into a single command string, so your local quoting is gone before\nthe remote shell sees it. A nested ",{"type":53,"tag":107,"props":173,"children":175},{"className":174},[],[176],{"type":37,"value":177},"bash -lc",{"type":37,"value":179}," then takes only the ",{"type":53,"tag":181,"props":182,"children":183},"strong",{},[184],{"type":37,"value":185},"first word",{"type":37,"value":187}," as its script:",{"type":53,"tag":189,"props":190,"children":195},"pre",{"className":191,"code":192,"language":193,"meta":194,"style":194},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","# ✗ prints a blank line, then the OUTER HOST's hostname\nssh root@\u003Chost> -- pct exec \u003Cctid> -- bash -lc 'echo hi; hostname'\n\n# ✓ prints \"hi\", then the container's hostname\nssh root@\u003Chost> \"pct exec \u003Cctid> -- bash -lc 'echo hi; hostname'\"\n","bash","",[196],{"type":53,"tag":107,"props":197,"children":198},{"__ignoreMap":194},[199,211,313,322,331],{"type":53,"tag":200,"props":201,"children":204},"span",{"class":202,"line":203},"line",1,[205],{"type":53,"tag":200,"props":206,"children":208},{"style":207},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit",[209],{"type":37,"value":210},"# ✗ prints a blank line, then the OUTER HOST's hostname\n",{"type":53,"tag":200,"props":212,"children":214},{"class":202,"line":213},2,[215,220,226,232,237,243,248,254,259,264,269,274,279,283,287,292,297,303,308],{"type":53,"tag":200,"props":216,"children":218},{"style":217},"--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0",[219],{"type":37,"value":14},{"type":53,"tag":200,"props":221,"children":223},{"style":222},"--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF",[224],{"type":37,"value":225}," root@",{"type":53,"tag":200,"props":227,"children":229},{"style":228},"--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583",[230],{"type":37,"value":231},"\u003C",{"type":53,"tag":200,"props":233,"children":234},{"style":222},[235],{"type":37,"value":236},"hos",{"type":53,"tag":200,"props":238,"children":240},{"style":239},"--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8",[241],{"type":37,"value":242},"t",{"type":53,"tag":200,"props":244,"children":245},{"style":228},[246],{"type":37,"value":247},">",{"type":53,"tag":200,"props":249,"children":251},{"style":250},"--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[252],{"type":37,"value":253}," --",{"type":53,"tag":200,"props":255,"children":256},{"style":222},[257],{"type":37,"value":258}," pct",{"type":53,"tag":200,"props":260,"children":261},{"style":222},[262],{"type":37,"value":263}," exec",{"type":53,"tag":200,"props":265,"children":266},{"style":228},[267],{"type":37,"value":268}," \u003C",{"type":53,"tag":200,"props":270,"children":271},{"style":222},[272],{"type":37,"value":273},"cti",{"type":53,"tag":200,"props":275,"children":276},{"style":239},[277],{"type":37,"value":278},"d",{"type":53,"tag":200,"props":280,"children":281},{"style":228},[282],{"type":37,"value":247},{"type":53,"tag":200,"props":284,"children":285},{"style":250},[286],{"type":37,"value":253},{"type":53,"tag":200,"props":288,"children":289},{"style":222},[290],{"type":37,"value":291}," bash",{"type":53,"tag":200,"props":293,"children":294},{"style":250},[295],{"type":37,"value":296}," -lc",{"type":53,"tag":200,"props":298,"children":300},{"style":299},"--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF",[301],{"type":37,"value":302}," '",{"type":53,"tag":200,"props":304,"children":305},{"style":222},[306],{"type":37,"value":307},"echo hi; hostname",{"type":53,"tag":200,"props":309,"children":310},{"style":299},[311],{"type":37,"value":312},"'\n",{"type":53,"tag":200,"props":314,"children":315},{"class":202,"line":23},[316],{"type":53,"tag":200,"props":317,"children":319},{"emptyLinePlaceholder":318},true,[320],{"type":37,"value":321},"\n",{"type":53,"tag":200,"props":323,"children":325},{"class":202,"line":324},4,[326],{"type":53,"tag":200,"props":327,"children":328},{"style":207},[329],{"type":37,"value":330},"# ✓ prints \"hi\", then the container's hostname\n",{"type":53,"tag":200,"props":332,"children":334},{"class":202,"line":333},5,[335,339,343,347,351,355,359,364,369],{"type":53,"tag":200,"props":336,"children":337},{"style":217},[338],{"type":37,"value":14},{"type":53,"tag":200,"props":340,"children":341},{"style":222},[342],{"type":37,"value":225},{"type":53,"tag":200,"props":344,"children":345},{"style":228},[346],{"type":37,"value":231},{"type":53,"tag":200,"props":348,"children":349},{"style":222},[350],{"type":37,"value":236},{"type":53,"tag":200,"props":352,"children":353},{"style":239},[354],{"type":37,"value":242},{"type":53,"tag":200,"props":356,"children":357},{"style":228},[358],{"type":37,"value":247},{"type":53,"tag":200,"props":360,"children":361},{"style":299},[362],{"type":37,"value":363}," \"",{"type":53,"tag":200,"props":365,"children":366},{"style":222},[367],{"type":37,"value":368},"pct exec \u003Cctid> -- bash -lc 'echo hi; hostname'",{"type":53,"tag":200,"props":370,"children":371},{"style":299},[372],{"type":37,"value":373},"\"\n",{"type":53,"tag":60,"props":375,"children":376},{},[377,379,385,387,393,395,401,403,409],{"type":37,"value":378},"Both exit 0. The broken form either runs everything after a ",{"type":53,"tag":107,"props":380,"children":382},{"className":381},[],[383],{"type":37,"value":384},";",{"type":37,"value":386}," or ",{"type":53,"tag":107,"props":388,"children":390},{"className":389},[],[391],{"type":37,"value":392},"&&",{"type":37,"value":394}," on the outer host, or runs\na bare first word with the rest discarded into ",{"type":53,"tag":107,"props":396,"children":398},{"className":397},[],[399],{"type":37,"value":400},"$@",{"type":37,"value":402},". It has already turned a healthy production\ncontainer into a report that the app directory was missing, the service inactive and ",{"type":53,"tag":107,"props":404,"children":406},{"className":405},[],[407],{"type":37,"value":408},"docker",{"type":37,"value":410}," not\ninstalled — every one of those true of the host, none of them true of the container.",{"type":53,"tag":60,"props":412,"children":413},{},[414,416,422,424,430,432,438],{"type":37,"value":415},"The same shape appears anywhere a remote command nests: ",{"type":53,"tag":107,"props":417,"children":419},{"className":418},[],[420],{"type":37,"value":421},"ssh … docker exec … sh -c '…'",{"type":37,"value":423},",\n",{"type":53,"tag":107,"props":425,"children":427},{"className":426},[],[428],{"type":37,"value":429},"ssh … sudo -u app bash -lc '…'",{"type":37,"value":431},", ",{"type":53,"tag":107,"props":433,"children":435},{"className":434},[],[436],{"type":37,"value":437},"ssh … kubectl exec … -- sh -c '…'",{"type":37,"value":155},{"type":53,"tag":66,"props":440,"children":442},{"id":441},"the-rule-worth-memorising",[443],{"type":37,"value":444},"The rule worth memorising",{"type":53,"tag":60,"props":446,"children":447},{},[448,460],{"type":53,"tag":181,"props":449,"children":450},{},[451,453,458],{"type":37,"value":452},"When a remote result surprises you, run ",{"type":53,"tag":107,"props":454,"children":456},{"className":455},[],[457],{"type":37,"value":130},{"type":37,"value":459}," before believing it.",{"type":37,"value":461}," \"Not found\", \"not\ninstalled\", \"no such directory\" is what a perfectly healthy outer host says when your command never\nreached the container.",{"type":53,"tag":66,"props":463,"children":465},{"id":464},"install",[466],{"type":37,"value":467},"Install",{"type":53,"tag":189,"props":469,"children":471},{"className":191,"code":470,"language":193,"meta":194,"style":194},"unzip remote-ops.zip\nmkdir -p .claude\u002Fskills\ncp -R remote-ops\u002Fskills\u002F. .claude\u002Fskills\u002F\ncat remote-ops\u002FCLAUDE.md >> CLAUDE.md\n",[472],{"type":53,"tag":107,"props":473,"children":474},{"__ignoreMap":194},[475,488,506,529],{"type":53,"tag":200,"props":476,"children":477},{"class":202,"line":203},[478,483],{"type":53,"tag":200,"props":479,"children":480},{"style":217},[481],{"type":37,"value":482},"unzip",{"type":53,"tag":200,"props":484,"children":485},{"style":222},[486],{"type":37,"value":487}," remote-ops.zip\n",{"type":53,"tag":200,"props":489,"children":490},{"class":202,"line":213},[491,496,501],{"type":53,"tag":200,"props":492,"children":493},{"style":217},[494],{"type":37,"value":495},"mkdir",{"type":53,"tag":200,"props":497,"children":498},{"style":250},[499],{"type":37,"value":500}," -p",{"type":53,"tag":200,"props":502,"children":503},{"style":222},[504],{"type":37,"value":505}," .claude\u002Fskills\n",{"type":53,"tag":200,"props":507,"children":508},{"class":202,"line":23},[509,514,519,524],{"type":53,"tag":200,"props":510,"children":511},{"style":217},[512],{"type":37,"value":513},"cp",{"type":53,"tag":200,"props":515,"children":516},{"style":250},[517],{"type":37,"value":518}," -R",{"type":53,"tag":200,"props":520,"children":521},{"style":222},[522],{"type":37,"value":523}," remote-ops\u002Fskills\u002F.",{"type":53,"tag":200,"props":525,"children":526},{"style":222},[527],{"type":37,"value":528}," .claude\u002Fskills\u002F\n",{"type":53,"tag":200,"props":530,"children":531},{"class":202,"line":324},[532,537,542,547],{"type":53,"tag":200,"props":533,"children":534},{"style":217},[535],{"type":37,"value":536},"cat",{"type":53,"tag":200,"props":538,"children":539},{"style":222},[540],{"type":37,"value":541}," remote-ops\u002FCLAUDE.md",{"type":53,"tag":200,"props":543,"children":544},{"style":228},[545],{"type":37,"value":546}," >>",{"type":53,"tag":200,"props":548,"children":549},{"style":222},[550],{"type":37,"value":551}," CLAUDE.md\n",{"type":53,"tag":60,"props":553,"children":554},{},[555,557,563,564,570,571,577,579,585],{"type":37,"value":556},"No configuration. The examples use ",{"type":53,"tag":107,"props":558,"children":560},{"className":559},[],[561],{"type":37,"value":562},"\u003Chost>",{"type":37,"value":431},{"type":53,"tag":107,"props":565,"children":567},{"className":566},[],[568],{"type":37,"value":569},"\u003Cctid>",{"type":37,"value":431},{"type":53,"tag":107,"props":572,"children":574},{"className":573},[],[575],{"type":37,"value":576},"\u003Capp>",{"type":37,"value":578}," and ",{"type":53,"tag":107,"props":580,"children":582},{"className":581},[],[583],{"type":37,"value":584},"\u003Ccontainer>",{"type":37,"value":586}," placeholders —\nsubstitute your own, and keep the project's real hosts in a project-local skill rather than here.",{"type":53,"tag":66,"props":588,"children":590},{"id":589},"requirements",[591],{"type":37,"value":592},"Requirements",{"type":53,"tag":594,"props":595,"children":596},"ul",{},[597],{"type":53,"tag":598,"props":599,"children":600},"li",{},[601,606,608,614],{"type":53,"tag":107,"props":602,"children":604},{"className":603},[],[605],{"type":37,"value":14},{"type":37,"value":607}," on PATH, and ",{"type":53,"tag":107,"props":609,"children":611},{"className":610},[],[612],{"type":37,"value":613},"base64",{"type":37,"value":615}," on both ends for the payload form.",{"type":53,"tag":617,"props":618,"children":619},"style",{},[620],{"type":37,"value":621},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"name":10,"description":11,"tags":623,"author":17,"authorUrl":18,"requires":624},[13,14,15,16],[14]]