bash别名与python3 -c命令

时间:2018-07-19 18:58:05

标签: python-3.x bash alias

我正在尝试通过在Mac上编写如下bash别名来缩短获取aws访问令牌并将其写入〜/ .aws / credentials文件的工作:

alias trial='function mfa(){ aws sts get-session-token --serial-number $2 --token-code $1|python3 -c "import sys,subprocess;obj=eval(''.join(sys.stdin.readlines()).replace('\n',''));AccessKeyId=obj['Credentials']['AccessKeyId'];SecretAccessKey=obj['Credentials']['SecretAccessKey'];SessionToken=obj['Credentials']['SessionToken'];subprocess.check_output('aws configure set aws_access_key_id '+AccessKeyId+' --profile mfa', shell=True);subprocess.check_output('aws configure set aws_secret_access_key '+SecretAccessKey+' --profile mfa', shell=True);subprocess.check_output('aws configure set aws_session_token '+SessionToken+' --profile mfa', shell=True);"};mfa'

但是由于某种原因,这不起作用。特别是bash编译器对python3 -c之后的部分不满意。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

不要使用别名,只需将函数命名为mfa。并将Python代码放入文件中。

mfa.py:

import sys, subprocess, json

obj=json.loads(sys.stdin.read())
AccessKeyId=obj['Credentials']['AccessKeyId']
SecretAccessKey=obj['Credentials']['SecretAccessKey']
SessionToken=obj['Credentials']['SessionToken']
subprocess.check_output(['aws', 'configure', 'set', 'aws_access_key_id', AccessKeyId, '--profile', 'mfa'])
subprocess.check_output(['aws', 'configure', 'set', 'aws_secret_access_key', SecretAccessKey, '--profile', 'mfa'])
subprocess.check_output(['aws', 'configure', 'set', 'aws_session_token', SessionToken, '--profile', 'mfa'])

请注意,我将列表提供给subprocess.check_output而不是构造字符串,因此不需要shell=True

然后定义函数:

mfa() {
    aws sts get-session-token --serial-number "$2" --token-code "$1" | python /path/to/mfa.py
}

我假设会话令牌是JSON,而不是Python语法,因此我使用json.loads()而不是eval()。要读取所有标准输入,请使用sys.stdin.read()而不是加入readlines();会不必要地创建列表,只需将其重新连接为一个长字符串即可。

答案 1 :(得分:2)

我根本不会使用Python。只需jq即可参加。

mfa() {
  [[ $1 && $2 ]] || {
    echo "Usage: mfa token-code serial-number" >&2
    return 1
  }
  token_json=$(aws sts get-session-token --serial-number "$2" --token-code "$1") || return
  IFS=$'\t' read -r accessKeyId secretAccessKey sessionToken _ < <(
    jq -r '
      .Credentials | [.AccessKeyId, .SecretAccessKey, .SessionToken] | @tsv
    ' <<<"$token_json"
  ) && [[ $accessKeyId && $secretAccessKey && $sessionToken ]] || return
  aws configure set aws_access_key_id "$accessKeyId" --profile mfa || return
  aws configure set aws_secret_access_key "$secretAccessKey" --profile mfa || return
  aws configure set aws_session_token "$sessionToken" --profile mfa
}

如果您确实希望将Python源代码嵌入.bashrc中,也可以这样做:

mfa_py=$(cat <<'END-OF-PYTHON'
# adopting fixes made by Barmar to the Python code here
import sys, subprocess, json

obj=json.loads(sys.stdin.read())
AccessKeyId=obj['Credentials']['AccessKeyId']
SecretAccessKey=obj['Credentials']['SecretAccessKey']
SessionToken=obj['Credentials']['SessionToken']
subprocess.check_output(['aws', 'configure', 'set', 'aws_access_key_id', AccessKeyId, '--profile', 'mfa'])
subprocess.check_output(['aws', 'configure', 'set', 'aws_secret_access_key', SecretAccessKey, '--profile', 'mfa'])
subprocess.check_output(['aws', 'configure', 'set', 'aws_session_token', SessionToken, '--profile', 'mfa'])
END-OF-PYTHON
)

mfa() {
  aws sts get-session-token --serial-number "$2" --token-code "$1" | python -c "$mfa_py"
}

在您的原始别名定义中,shell会将引号显然是原义的引号解析为语法,因此Python解释器仍无法读取它们。

在这里,我们使用带引号的heredoc来确保<<'END-OF-PYTHON'END-OF-PYTHON之间的所有内容(包括引号)都被视为文字。

答案 2 :(得分:0)

感谢大家的答复。最终,我最终将所有内容都放入了这样的python文件中:

<div id="button-wrap">
    <input type="button" class="btn btn-default" value="1" data-index="0">
    <input type="button" class="btn btn-default" value="2" data-index="1">
    <input type="button" class="btn btn-default" value="3" data-index="2">
    <input type="button" class="btn btn-default" value="4" data-index="3">
    <input type="button" class="btn btn-default" value="5" data-index="4">
    <input type="button" class="btn btn-default" value="6" data-index="5">

  </div>
</div>

然后在bash_profile上,我有一个别名:

<div id="button-wrap">

  <a href="#" class="previous"> &lt; </a>   
  <a href="#" class="now"> Current </a>  
  <a href="#" class="next">&gt; </a>  

<div>

这正在起作用。但是如果我在别名中添加更多命令,它将停止工作。试图找出答案。例如:

import sys, subprocess, json
output = subprocess.Popen('aws sts get-session-token --serial-number sys.argv[2] --token-code '+sys.argv[1], shell=True,stdout=subprocess.PIPE)
output = json.loads(output.communicate()[0].decode('utf-8').strip())
AccessKeyId=output['Credentials']['AccessKeyId']
SecretAccessKey=output['Credentials']['SecretAccessKey']
SessionToken=output['Credentials']['SessionToken']
subprocess.check_output('aws configure set aws_access_key_id '+AccessKeyId+' --profile mfa', shell=True)
subprocess.check_output('aws configure set aws_secret_access_key '+SecretAccessKey+' --profile mfa', shell=True)
subprocess.check_output('aws configure set aws_session_token '+SessionToken+' --profile mfa', shell=True)

不起作用。