Python 3.x 使用python3-c命令的bash别名

Python 3.x 使用python3-c命令的bash别名,python-3.x,bash,alias,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',''));AccessKe

我试图通过在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之后的部分不满意。有人能帮忙吗?

不要使用别名,只需命名函数
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'])
请注意,我为
子流程提供了一个列表。请检查输出,而不是构造字符串,这样就不需要
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()
;这不必要地创建了一个列表,只是为了将其重新连接成一个长字符串。

不要使用别名,只需命名函数
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'])
请注意,我为
子流程提供了一个列表。请检查输出,而不是构造字符串,这样就不需要
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()
;这不必要地创建了一个列表,只是为了将它重新连接成一个长字符串。

我根本不会使用Python来实现这一点;带
jq
的bash就足够了

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
}
在最初的别名定义中,shell将那些显然是文字的引号解析为语法,因此Python解释器仍然无法读取它们


在这里,我们使用一个引用的herdoc来确保
之间的所有内容都不会使用Python;带
jq
的bash就足够了

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
}
在最初的别名定义中,shell将那些显然是文字的引号解析为语法,因此Python解释器仍然无法读取它们


在这里,我们使用引用的herdoc来确保
之间的所有内容都感谢大家的回复。最终,我将所有内容都放在一个python文件中,如下所示:

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)
然后在bash_配置文件中,我有一个别名:

alias a="python3 ~/bin/python3_mfa.py $1"
这是有效的。但如果我在别名中添加更多命令,它将停止工作。想弄明白。例如:

alias a="python3 ~/bin/python3_mfa.py $1;eb ssh env --profile mfa;"

不起作用。

谢谢大家的回复。最终,我将所有内容都放在一个python文件中,如下所示:

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)
然后在bash_配置文件中,我有一个别名:

alias a="python3 ~/bin/python3_mfa.py $1"
这是有效的。但如果我在别名中添加更多命令,它将停止工作。想弄明白。例如:

alias a="python3 ~/bin/python3_mfa.py $1;eb ssh env --profile mfa;"


不起作用。

我建议使用函数。请参阅:
help function
。我已经在使用您可以从我的别名字符串中看到的函数。为什么您需要函数的别名?您只需将函数命名为您想要命名的别名。实际上,它很难读取。问题是在函数中使用单引号,但单引号也是别名周围的分隔符。这会产生无效的语法。不要添加问题的答案;将其作为实际答案发布。我建议使用函数。请参阅:
help function
。我已经在使用您可以从我的别名字符串中看到的函数。为什么您需要函数的别名?您只需将函数命名为您想要命名的别名。实际上,它很难读取。问题是在函数中使用单引号,但单引号也是别名周围的分隔符。这会产生无效的语法。不要添加问题的答案;将其作为实际答案发布。谢谢。最后,我将所有内容都放在python文件中,并使用alias调用该python文件。编辑了我的问题以包含答案。@tejas,…即使在那时,你为什么还要使用别名?我可能只看到这样一种情况:一个别名比一个函数更适合一年一次的用途,如果是这样的话;你在这里所做的一切并没有让它成为这些案例中的一个。是的,我真傻,竟然顽固地使用别名。意识到函数工作得更好。谢谢。最后,我将所有内容都放在python文件中,并使用alias调用该python文件。编辑了我的问题以包含答案。@tejas,…即使在那时,你为什么还要使用别名?我可能只看到这样一种情况:一个别名比一个函数更适合一年一次的用途,如果是这样的话;你在这里所做的一切并没有让它成为这些案例中的一个。是的,我真傻,竟然顽固地使用别名。意识到函数工作得更好。谢谢。最后,我将所有内容都放在python文件中,并使用alias调用该python文件。编辑我的问题以包含答案。谢谢。最后,我将所有内容都放在python文件中,并使用alias调用该python文件。编辑了我的问题以包含答案。
$1
此处未提及别名的参数,因为别名根本没有参数(这就是为什么freenode#bash频道中有关别名问题的自反式答案是“如果必须提问,请改用函数”)。尝试运行
set--“这是$1”这是$2
,然后运行别名
a
;您将看到它运行
python3~/bin/python3_mfa.py这是$1;eb ssh env--profile mfa
除了
$1
实际工作的地方之外,等效函数是
a(){python3~/bin/python3_mfa.py“$1”;eb ssh env--profile mfa;}
…别名只是文本前缀替换--它们没有调用堆栈位置。没有调用堆栈->没有参数,没有局部变量,没有返回值,等等。另一方面--