[{"data":1,"prerenderedAt":450},["ShallowReactive",2],{"project-24249646":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":28,"sentiment":29,"stance_mix":30,"scored_comments":35,"aspects":36,"strip":47,"post_text":49,"what":50,"said":76,"maker_in_thread":179,"shape":189,"grid":193,"attempts":409,"same_week":414,"maker_shows":33,"maker_hidden":442,"reader_version":443,"card":444},"24249646","rust_cmd_lib","Using Rust to write shell-script like tasks","title","Show HN: Using Rust to write shell-script like tasks","https:\u002F\u002Fgithub.com\u002Frust-shell-script\u002Frust_cmd_lib","github.com","rustshellscript",1598159071,2020,231,80,221,3028,8,"notable","dev_tools","shell scripting library","library",[24,25,26,27],"rust","shell script","process spawning","command macros","mixed",-0.073,{"positive":31,"neutral":32,"mixed":33,"critical":34},5,10,1,14,30,{"idea":37,"design":40,"docs":41,"performance":43,"privacy":44,"execution":46},{"positive":38,"critical":39},4,6,{"positive":33,"critical":31},{"positive":42,"critical":33},0,{"positive":42,"critical":42},{"positive":42,"critical":45},2,{"positive":42,"critical":42},[31,48,33,48,33,33,33,33,42,48,42,42,42,48,42,33,42,42,42,42,48,31,31,42,42,42,48,42,48,33,33,31,33,33,33,33,33,48,42,42],3,null,{"problem":51,"audience":49,"pricing":49,"motivation":49,"time_to_build":49,"stack":67,"openness":74,"stage":75,"team_size":75},{"value":52,"source":53,"evidence":54},"Writing shell-script-like tasks in a safer, more structured way than bash","commenter",[55,59,63],{"id":56,"by":57,"text":58},"24250238","yisonPylkita","My god, this super useful when you have a mix o shell commands and processing text output from them. Bash isn’t particularly easy to work with parsing non-trivial strings in a…",{"id":60,"by":61,"text":62},"24250504","Fiahil","This is great! What about \"set -euxo pipefail\"? I see you were using eprintln before the commands, could we have a \"set\" macro that would do that for us?",{"id":64,"by":65,"text":66},"24251605","rossmohax","Nothing can fix the fact, that pipes carry dumb byte streams. Powershell addressed this, but sadly remains unpopular in Unix crowd",[68],{"value":69,"source":70,"evidence":71},"Rust","maker",[72],{"id":73},"post","open_source","unknown",{"praise":77,"objections":94,"requests":122,"questions":131,"alternatives":146},[78,86],{"value":79,"source":53,"evidence":80},"Useful for mixing shell commands with text processing; hygienic approach to splicing commands",[81,85],{"id":82,"by":83,"text":84},"24250207","jitl","I love this. I tried to do something similar in Go, because it was in use on my team at Airbnb, and we were looking to port a 2000 line make-and-bash tool to... something not…",{"id":56,"by":57,"text":58},{"value":87,"source":53,"evidence":88},"Better than bash for error handling and parsing",[89,93],{"id":90,"by":91,"text":92},"24258129","implfuture","This is so awesome! Any tips on parallelizing\u002Fis it async compatible? I personally found granular error handling combined with parallelization to be impossible to get just right…",{"id":56,"by":57,"text":58},[95,108,115],{"value":96,"source":53,"evidence":97},"Inlining shell code in Rust hides external command calls from auditing",[98,102,105],{"id":99,"by":100,"text":101},"24250239","laumars","Please people, don’t do stuff like this for anything other than personal projects. You might think it’s safer than writing Bash but it isn’t. It results in unsafe Rust code since…",{"id":103,"by":100,"text":104},"24250550","It’s inside a .rs file so I don’t see how it’s not unsafe in the Rust sense. Maybe when I drew parallels with the “unsafe” block wasn’t fair but safety isn’t just about memory…",{"id":106,"by":100,"text":107},"24251159","> I'll reiterate: it is often safer to embed short snippets of bash into other languages than to invert control and call out to other languages from bash. By calling out to bash,…",{"value":109,"source":53,"evidence":110},"Embedding a shell-like syntax in macros risks passing shell metacharacters to a shell",[111],{"id":112,"by":113,"text":114},"24250256","rhn_mk1","I am not a huge fan of copying the shell language wholesale and wrapping inside a macro. Since macros can execute arbitrary code, this makes me feel uneasy that the strings are…",{"value":116,"source":53,"evidence":117},"Shell is best kept as a DSL for files and streams; Rust macros unlikely to beat it",[118],{"id":119,"by":120,"text":121},"24250489","geowwy","``` > A lot developers just choose shell(sh, bash, ...) scripts for such tasks, > by using \u003C to redirect input, > to redirect output and '|' to pipe outputs. > In my experience,…",[123,127],{"value":124,"source":53,"evidence":125},"Support for set -euxo pipefail style options",[126],{"id":60,"by":61,"text":62},{"value":128,"source":53,"evidence":129},"Parallel and async support",[130],{"id":90,"by":91,"text":92},[132,139],{"value":133,"source":53,"evidence":134},"How are binary names resolved and does it use a shell",[135,136],{"id":112,"by":113,"text":114},{"id":137,"by":11,"text":138},"24251372","Author here, thanks for your feedback. This library is calling std::process::command underneath without any shell dependency, which I believe is the same as plumbum’s run* APIs…",{"value":140,"source":53,"evidence":141},"How does Rust parse the macro contents",[142],{"id":143,"by":144,"text":145},"24257514","gitgud","Interesting, it seems that it allows the exact syntax of shell commands, without using strings. ``` \u002F\u002F valid rust code and shell code, no strings run_cmd!(du -ah . | sort -hr |…",[147,151,158,165,172],{"value":148,"source":53,"evidence":149},"Plumbum (Python)",[150],{"id":112,"by":113,"text":114},{"value":152,"source":53,"evidence":153},"xonsh",[154],{"id":155,"by":156,"text":157},"24250838","LockAndLol","This reminds me of the python version of this called xonsh https:\u002F\u002Fxon.sh\u002F I really like the idea, but it was missing some simple features that bash had. I can't recall them…",{"value":159,"source":53,"evidence":160},"duct.rs",[161],{"id":162,"by":163,"text":164},"24251755","oconnor663","I'm going to shamelessly plug my own library here: https:\u002F\u002Fgithub.com\u002Foconnor663\u002Fduct.rs I wanted to solve the same problem, originally in Python…",{"value":166,"source":53,"evidence":167},"scriptisto",[168],{"id":169,"by":170,"text":171},"24257392","lugoues","There is also https:\u002F\u002Fgithub.com\u002Figor-petruk\u002Fscriptisto which would allow you to wrap any compiled language.",{"value":173,"source":53,"evidence":174},"khaki",[175],{"id":176,"by":177,"text":178},"24252321","staktrace","I wrote a tool to do the opposite thing: allow writing \"shell scripts\" using Rust. Still early days but https:\u002F\u002Fgithub.com\u002Fstaktrace\u002Fkhaki is where it lives.",{"comments":180,"answered":45,"key":181},7,[182,185,188],{"id":183,"text":184},"24252873","Unquoted argument is not an issue here, see some examples here: https:\u002F\u002Fgithub.com\u002Frust-shell-script\u002Frust_cmd_lib\u002Fissues\u002F10",{"id":186,"text":187},"24252822","since run_cmd! and run_fun! are returning result type, you can always do let _ = run_cmd!(ls nofile); to ignore single command error. The “xxx || true” is for ignoring error…",{"id":137,"text":138},{"commenters":190,"max_depth":32,"maker_replies":180,"first_comment_mins":191,"lifespan_hours":192},54,131,27,[194,196,198,202,205,208,210,214,218,220,221,225,229,233,235,237,239,243,245,247,250,253,256,259,262,264,266,270,272,276,278,280,282,285,288,291,294,297,299,301,304,306,309,313,315,316,318,321,325,327,330,333,336,337,339,342,343,346,350,354,357,362,364,367,371,374,377,379,382,383,385,387,389,390,392,395,398,401,404,406],[82,42,31,195,83,42],"project\u002Fpositive\u002Fidea",[143,33,48,197,144,42],"project\u002Fneutral\u002Fidea",[199,33,42,200,201,42],"24257522","other\u002Fneutral\u002Fnone","steveklabnik",[203,33,48,197,204,42],"24257543","qwertycrackers",[206,33,42,200,207,42],"24258107","gabssnake",[112,45,33,209,113,42],"project\u002Fcritical\u002Fdesign",[211,45,42,212,213,42],"24250484","commenter\u002Fcritical\u002Fdesign","IshKebab",[215,45,48,216,217,42],"24250930","project\u002Fneutral\u002Fdesign","foota",[219,45,33,209,213,42],"24252529",[183,45,42,216,11,33],[222,45,42,223,224,42],"24250815","commenter\u002Fcritical\u002Fnone","papaf",[226,45,33,227,228,42],"24251221","project\u002Fcritical\u002Fdocs","viraptor",[230,45,42,231,232,42],"24251825","commenter\u002Fneutral\u002Fdocs","rattray",[234,45,33,209,113,42],"24252569",[186,45,42,236,11,33],"project\u002Fneutral\u002Fdocs",[238,45,33,209,113,42],"24253001",[240,45,42,241,242,42],"24251027","other\u002Fpositive\u002Fnone","cheez",[137,45,42,244,11,33],"maker\u002Fneutral\u002Fdocs",[56,48,48,246,57,42],"project\u002Fneutral\u002Fnone",[248,48,42,200,249,42],"24250493","scns",[251,48,42,200,252,42],"24250629","enhray",[254,48,42,200,255,42],"24250567","ilovetux",[257,48,42,200,258,42],"24254168","qchris",[260,48,42,200,261,42],"24250842","thesuperbigfrog",[162,38,42,263,163,42],"other\u002Fneutral\u002Fdesign",[265,38,42,216,11,33],"24252040",[267,38,31,268,269,42],"24252122","project\u002Fpositive\u002Fdesign","joobus",[271,38,33,209,100,42],"24252447",[273,38,42,274,275,42],"24253909","commenter\u002Fneutral\u002Fdesign","dllthomas",[277,38,42,212,100,42],"24254158",[279,38,42,274,275,42],"24254664",[119,31,33,281,120,42],"project\u002Fcritical\u002Fidea",[283,31,42,200,284,42],"24250628","masklinn",[286,31,42,200,287,42],"24250976","dijit",[289,31,42,200,290,42],"24251405","amalcon",[292,31,42,200,293,42],"24250689","jabirali",[295,31,42,200,296,42],"24250945","barrkel",[298,31,42,200,293,42],"24251238",[300,31,42,200,228,42],"24251262",[302,31,42,303,11,33],"24251481","maker\u002Fneutral\u002Fexecution",[305,31,42,200,228,42],"24251246",[307,31,48,197,308,42],"24251048","usrusr",[310,31,42,311,312,42],"24251570","other\u002Fcritical\u002Fnone","dathinab",[314,31,31,195,232,42],"24251858",[155,39,31,195,156,42],[317,39,42,303,11,33],"24251537",[319,39,42,200,320,42],"24254132","oldsj",[322,39,42,323,324,42],"24254491","other\u002Fneutral\u002Fidea","Siira",[64,180,42,326,65,42],"other\u002Fcritical\u002Fidea",[328,180,42,200,329,42],"24252475","hnlmorg",[331,180,42,200,332,42],"24258486","carlmr",[334,180,42,200,335,42],"24256382","eska",[176,18,42,200,177,42],[60,338,48,216,61,42],9,[340,338,42,341,11,33],"24251502","maker\u002Fneutral\u002Fdesign",[169,32,42,200,170,42],[90,344,48,345,91,42],11,"project\u002Fneutral\u002Fperformance",[347,348,48,246,349,42],"24251875",12,"sneak",[351,352,48,197,353,42],"24253298",13,"ausjke",[355,34,33,281,356,42],"24250891","barrenko",[358,359,48,360,361,42],"24250686",15,"project\u002Fmixed\u002Fidea","darthrupert",[363,359,33,281,100,42],"24251115",[365,359,31,195,366,42],"24251967","MetaDark",[368,359,42,369,370,42],"24253163","commenter\u002Fneutral\u002Fnone","Ar-Curunir",[99,372,33,373,100,42],16,"project\u002Fcritical\u002Fprivacy",[375,372,42,369,376,42],"24250264","kazinator",[378,372,33,373,100,42],"24250339",[380,372,42,369,381,42],"24250462","joshuamorton",[103,372,33,281,100,42],[384,372,42,369,381,42],"24250591",[386,372,33,281,100,42],"24250631",[388,372,42,369,381,42],"24250774",[106,372,33,281,100,42],[391,372,42,369,376,42],"24253302",[393,372,42,369,394,42],"24250679","lpwq",[396,372,48,397,376,42],"24253144","project\u002Fneutral\u002Fexecution",[399,372,42,369,400,42],"24250593","intc",[402,372,42,369,403,42],"24251092","feanaro",[405,372,42,369,376,42],"24253054",[407,372,42,369,408,42],"24252457","zelphirkalt",[410,413],{"id":411,"t":412,"points":45,"comments":33},"21088862",1569563661,{"id":4,"t":12,"points":14,"comments":15},[415,420,425,429,433,437],{"id":416,"name":417,"points":418,"category":419},"24286335","ztext.js",257,"languages",{"id":421,"name":422,"points":423,"category":424},"24258098","ultimate-go",185,"learning_science",{"id":426,"name":427,"points":428,"category":20},"24221708","Analysis Tools",175,{"id":430,"name":431,"points":432,"category":20},"24269609","Will It CORS?",152,{"id":434,"name":435,"points":436,"category":20},"24280413","Vim-Like Layer for Xorg and Wayland",148,{"id":438,"name":439,"points":440,"category":441},"24240680","ePaper.js",145,"hardware",false,"v2",{"id":445,"name":5,"line":6,"ai":442,"cat":20,"year":13,"points":14,"comments":15,"rec":28,"s":446,"top":18,"kw":447,"maker":11,"domain":10,"tier":19,"attempts":45,"strip":448,"url":9,"mix":449,"praise":79,"objection":96,"sub":21},24249646,-0.07,[24,25,26,27],"5313111103000301000035500030311511111300",[31,32,33,34],1793991014980]