write to a sysfs file using golang

blov · · 632 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>A bit of context. My OS is Fedora and my laptop is a MacBook Air. The default key mappings for screen brightness don&#39;t work out of the box, so i have to implement them myself. This can be done by writing an &#34;acceptable&#34; value to /sys/class/backlight/intel_backlight/brightness. So I was writing a script to do exactly this, but when i try to write to the file, i keep getting the error : write &lt;filename&gt; invalid argument.</p> <p>How Could one write to a sysfile using golang? doing this... is it a bad ideia? any sugestions?</p> <p>I was able to do it using python. Could someone explain me the different behaviour between the two languages? Thanks </p> <hr/>**评论:**<br/><br/>hobbified: <pre><p>As <a href="/u/tv64738" rel="nofollow">/u/tv64738</a> says, the handlers for the pseudo-files in /sys, /proc, etc. can respond with anything they like to a write op, and they will usually error EINVAL if the data isn&#39;t in the format they expect. Looking at the code in backlight.c, the possible causes are either:</p> <ol> <li>The string you sent doesn&#39;t parse (it should be an optional <code>+</code> followed by 1 or more decimal digits, followed by optional newline; or <code>0</code> followed by one or more octal digits, followed by optional newline; or <code>0x</code> followed by one or more hex digits, followed by optional newline), or</li> <li>It parses, but represents an invalid value (in this case, greater than the backlight&#39;s <code>max_brightness</code>).</li> </ol></pre>seomisS: <pre><p>I just woke up what you and <a href="/u/tv64738" rel="nofollow">/u/tv64738</a> wrote... You guys are spot on, if i replace it with a string with a valid number it works!</p> <p>Thank you so much for pointing me to the right direction!!</p></pre>cfsalguero: <pre><p>Can you share the code? a gist maybe?</p></pre>seomisS: <pre><p>Yes, no problem.</p> <pre><code>data:=[]byte(string(n)) f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 644) if err != nil { return err } n, err := f.Write(data) if err == nil &amp;&amp; n &lt; len(data) { err = io.ErrShortWrite } if err1 := f.Close(); err == nil { err = err1 } return err } </code></pre> <p>Any feedback is appreciated</p></pre>denise-bryson: <pre><p>Your error is most likely caused by this <code>data:=[]byte(string(n))</code>. If you need to convert numbers into strings, use <a href="https://golang.org/pkg/strconv/" rel="nofollow">strconv</a> (<a href="https://golang.org/pkg/fmt/#Sprintf" rel="nofollow">fmt.Sprintf</a> is also handy in some situations).</p> <p>The conversion <code>string(140)</code> doesn&#39;t do what you think it does. Search for <code>Conversions to and from a string type</code> in the <a href="https://golang.org/ref/spec#Conversions" rel="nofollow">spec</a>.</p></pre>seomisS: <pre><p>It seems to me that the problem is related to the Apple Hardware. I just runned the code on another computer and it worked. Anyone has any idea of what is happening?</p></pre>jerf: <pre><p>I don&#39;t think you can os.CREATE that file. I don&#39;t know what the right flags are because I don&#39;t have a Mac, but play with those flags a bit.</p></pre>seomisS: <pre><p>Thanks for the answer. You are right, i shouldn&#39;t have a os.Create, just O_WRONLY since the file doesn&#39;t exist i don&#39;t want to create it. Even so, in this case, i don&#39;t think it makes a difference because the file exists so first option prevail. Still, i did what you suggested. Tried multiple combinations of O_RDWR O_APPEND O_SYNC and O_TRUNC without success</p></pre>etherealflaim: <pre><p>Your error looks like it&#39;s coming from write, not from open, but you don&#39;t add context from your error messages before returning them. I&#39;d suggest doing that and posting a playground link or a gist with the full code you&#39;re using in Go and the working Python script.</p></pre>seomisS: <pre><p>You are right, my error is coming from write. I should have mention that. printing the error gives: write &lt;filename&gt; invalid argument. Sample code in playground: <a href="https://play.golang.org/p/1Pw-iswC3N" rel="nofollow">https://play.golang.org/p/1Pw-iswC3N</a></p> <p>Python code:</p> <pre><code> fh = open(&#34;/sys/class/backlight/intel_backlight/brightness&#34;, &#34;w&#34;) fh.write(str(brightness)) fh.close() </code></pre></pre>epiris: <pre><p>Everything in sysfs is exported in kernel space, the /sys/class directory is going to be a symlink to /sys/devices which are all owned by root. The devices that support writes will be 0644 in all cases I can think of. So I would add the script to your /etc/sudoers for your user and alias it in your bash/zsh/whatever if it&#39;s more convenient. The only flag you want to provide is os.O_WRONLY and nothing else. Have fun.</p></pre>nirs: <pre><p>Whats wrong with:</p> <pre><code>echo &#34;data&#34; &gt; /sys/class/backlight/intel_backlight/brightness </code></pre> <p>You can write this in go or any other language, but why?</p></pre>epiris: <pre><p>It is probably done conditionally, perhaps it reads values first and does smoothing or something which wouldn&#39;t be very fun in sh. Regardless &#34;why not&#34; is a question of similar merit though.</p></pre>seomisS: <pre><p>you are absolutely right. Still, my bash script skill&#39;s are non-existent and i didn&#39;t want to call the command from go. But... maybe this time bash script makes more sense </p></pre>tv64738: <pre><p>Most of those pseudofiles give you an <code>EINVAL</code> (&#34;invalid argument&#34;) error if the data you give them isn&#39;t in the format they expect. Be careful about final newlines etc.</p></pre>seomisS: <pre><p>You really helped me, it was exactly this. Thank you so much for taking the time of reading the post and help me.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

632 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传